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/phase_diagram.tex
51 views
unlisted
1
\documentclass[11pt,a4paper]{article}
2
3
% Document Setup
4
\usepackage[utf8]{inputenc}
5
\usepackage[T1]{fontenc}
6
\usepackage{lmodern}
7
\usepackage[margin=1in]{geometry}
8
\usepackage{amsmath,amssymb}
9
\usepackage{siunitx}
10
\usepackage{booktabs}
11
\usepackage{float}
12
\usepackage{caption}
13
\usepackage{hyperref}
14
15
% PythonTeX Setup
16
\usepackage[makestderr]{pythontex}
17
18
\title{Binary Phase Diagrams: Computational Analysis}
19
\author{Materials Engineering Laboratory}
20
\date{\today}
21
22
\begin{document}
23
\maketitle
24
25
\begin{abstract}
26
This report presents computational analysis of binary phase diagrams in materials science. We examine isomorphous and eutectic systems, the lever rule for phase fraction calculations, cooling curve analysis, and Gibbs phase rule applications. Python-based computations provide quantitative analysis with dynamic visualization.
27
\end{abstract}
28
29
\tableofcontents
30
\newpage
31
32
\section{Introduction to Phase Diagrams}
33
34
Phase diagrams are graphical representations of the equilibrium phases present in a material system as a function of temperature, pressure, and composition. They are essential for:
35
\begin{itemize}
36
\item Predicting microstructure evolution during solidification
37
\item Designing heat treatment processes
38
\item Understanding alloy behavior and properties
39
\item Optimizing casting and welding procedures
40
\end{itemize}
41
42
% Initialize Python environment
43
\begin{pycode}
44
import numpy as np
45
import matplotlib.pyplot as plt
46
from scipy.optimize import fsolve
47
from scipy.interpolate import interp1d
48
49
plt.rcParams['figure.figsize'] = (8, 5)
50
plt.rcParams['font.size'] = 10
51
plt.rcParams['text.usetex'] = True
52
53
def save_fig(filename):
54
plt.savefig(filename, dpi=150, bbox_inches='tight')
55
plt.close()
56
\end{pycode}
57
58
\section{Gibbs Phase Rule}
59
60
The Gibbs phase rule determines the degrees of freedom in a system:
61
\begin{equation}
62
F = C - P + 2
63
\end{equation}
64
where $F$ is degrees of freedom, $C$ is number of components, and $P$ is number of phases.
65
66
For a binary system ($C=2$) at constant pressure:
67
\begin{equation}
68
F = 3 - P
69
\end{equation}
70
71
\begin{pycode}
72
# Gibbs phase rule visualization
73
phases = [1, 2, 3]
74
freedom = [3 - p for p in phases]
75
76
fig, ax = plt.subplots(figsize=(8, 5))
77
78
bars = ax.bar(phases, freedom, color=['green', 'blue', 'red'], alpha=0.7)
79
ax.set_xlabel('Number of Phases (P)')
80
ax.set_ylabel('Degrees of Freedom (F)')
81
ax.set_title('Gibbs Phase Rule for Binary System at Constant Pressure')
82
ax.set_xticks(phases)
83
84
for bar, f in zip(bars, freedom):
85
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.1,
86
f'F = {f}', ha='center', fontsize=12)
87
88
ax.grid(True, alpha=0.3, axis='y')
89
save_fig('gibbs_phase_rule.pdf')
90
\end{pycode}
91
92
\begin{figure}[H]
93
\centering
94
\includegraphics[width=0.7\textwidth]{gibbs_phase_rule.pdf}
95
\caption{Gibbs phase rule showing degrees of freedom for different numbers of phases.}
96
\end{figure}
97
98
\section{Isomorphous System}
99
100
An isomorphous system exhibits complete solid solubility. The Cu-Ni system is a classic example.
101
102
\begin{pycode}
103
# Cu-Ni isomorphous phase diagram
104
# Liquidus and solidus curves (simplified model)
105
x_Ni = np.linspace(0, 100, 200) # wt% Ni
106
107
# Melting points: Cu = 1085 C, Ni = 1455 C
108
T_Cu = 1085
109
T_Ni = 1455
110
111
# Liquidus curve (quadratic model)
112
T_liquidus = T_Cu + (T_Ni - T_Cu) * (x_Ni/100) + 20 * (x_Ni/100) * (1 - x_Ni/100)
113
114
# Solidus curve (offset from liquidus)
115
T_solidus = T_Cu + (T_Ni - T_Cu) * (x_Ni/100) - 30 * (x_Ni/100) * (1 - x_Ni/100)
116
117
fig, ax = plt.subplots(figsize=(10, 7))
118
119
ax.plot(x_Ni, T_liquidus, 'b-', linewidth=2, label='Liquidus')
120
ax.plot(x_Ni, T_solidus, 'r-', linewidth=2, label='Solidus')
121
122
# Fill regions
123
ax.fill_between(x_Ni, T_liquidus, 1500, alpha=0.3, color='yellow', label='Liquid (L)')
124
ax.fill_between(x_Ni, T_solidus, 900, alpha=0.3, color='lightblue', label='Solid ($\\alpha$)')
125
ax.fill_between(x_Ni, T_solidus, T_liquidus, alpha=0.3, color='lightgreen', label='L + $\\alpha$')
126
127
# Tie line example
128
x_0 = 40 # Overall composition
129
T_tie = 1250
130
idx_liq = np.argmin(np.abs(T_liquidus - T_tie))
131
idx_sol = np.argmin(np.abs(T_solidus - T_tie))
132
x_L = x_Ni[idx_liq]
133
x_alpha = x_Ni[idx_sol]
134
135
ax.plot([x_L, x_alpha], [T_tie, T_tie], 'k-', linewidth=2)
136
ax.plot(x_0, T_tie, 'ko', markersize=10)
137
ax.plot(x_L, T_tie, 'bo', markersize=8)
138
ax.plot(x_alpha, T_tie, 'ro', markersize=8)
139
140
ax.annotate(f'$C_0$ = {x_0}\\%', (x_0, T_tie), xytext=(x_0+5, T_tie+30),
141
fontsize=10, arrowprops=dict(arrowstyle='->', color='black'))
142
143
ax.set_xlabel('Composition (wt\\% Ni)')
144
ax.set_ylabel('Temperature ($^\\circ$C)')
145
ax.set_title('Cu-Ni Isomorphous Phase Diagram')
146
ax.legend(loc='upper left')
147
ax.set_xlim(0, 100)
148
ax.set_ylim(900, 1500)
149
ax.grid(True, alpha=0.3)
150
151
save_fig('isomorphous_diagram.pdf')
152
\end{pycode}
153
154
\begin{figure}[H]
155
\centering
156
\includegraphics[width=\textwidth]{isomorphous_diagram.pdf}
157
\caption{Cu-Ni isomorphous phase diagram with tie line construction at $T = 1250^{\circ}$C.}
158
\end{figure}
159
160
\section{The Lever Rule}
161
162
The lever rule calculates phase fractions in a two-phase region:
163
\begin{equation}
164
W_{\alpha} = \frac{C_L - C_0}{C_L - C_{\alpha}} \quad \text{and} \quad W_L = \frac{C_0 - C_{\alpha}}{C_L - C_{\alpha}}
165
\end{equation}
166
167
\begin{pycode}
168
# Lever rule calculation
169
C_0 = 40 # Overall composition
170
T_analysis = np.linspace(T_solidus[int(C_0*2)], T_liquidus[int(C_0*2)], 50)
171
172
# Interpolate liquidus and solidus
173
f_liquidus = interp1d(T_liquidus, x_Ni)
174
f_solidus = interp1d(T_solidus, x_Ni)
175
176
W_liquid = []
177
W_solid = []
178
temps = []
179
180
for T in T_analysis:
181
# Find compositions at this temperature
182
try:
183
C_L = f_liquidus(T)
184
C_alpha = f_solidus(T)
185
if C_L > C_alpha:
186
w_L = (C_0 - C_alpha) / (C_L - C_alpha)
187
w_alpha = (C_L - C_0) / (C_L - C_alpha)
188
W_liquid.append(w_L * 100)
189
W_solid.append(w_alpha * 100)
190
temps.append(T)
191
except:
192
pass
193
194
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
195
196
# Phase fractions vs temperature
197
ax1.plot(temps, W_liquid, 'b-', linewidth=2, label='Liquid')
198
ax1.plot(temps, W_solid, 'r-', linewidth=2, label='Solid ($\\alpha$)')
199
ax1.set_xlabel('Temperature ($^\\circ$C)')
200
ax1.set_ylabel('Phase Fraction (\\%)')
201
ax1.set_title(f'Phase Fractions during Cooling ($C_0$ = {C_0}\\% Ni)')
202
ax1.legend()
203
ax1.grid(True, alpha=0.3)
204
205
# Lever rule visualization
206
T_demo = 1250
207
C_L_demo = 35
208
C_alpha_demo = 48
209
C_0_demo = 40
210
211
ax2.plot([0, 100], [0, 0], 'k-', linewidth=3)
212
ax2.plot(C_L_demo, 0, 'b^', markersize=15, label=f'Liquid ({C_L_demo}\\%)')
213
ax2.plot(C_alpha_demo, 0, 'rs', markersize=15, label=f'Solid ({C_alpha_demo}\\%)')
214
ax2.plot(C_0_demo, 0, 'go', markersize=12, label=f'Overall ({C_0_demo}\\%)')
215
216
# Lever arms
217
ax2.annotate('', xy=(C_L_demo, 0.2), xytext=(C_0_demo, 0.2),
218
arrowprops=dict(arrowstyle='<->', color='blue', lw=2))
219
ax2.text((C_L_demo+C_0_demo)/2, 0.3, f'{C_0_demo-C_L_demo}', ha='center', fontsize=12, color='blue')
220
221
ax2.annotate('', xy=(C_0_demo, -0.2), xytext=(C_alpha_demo, -0.2),
222
arrowprops=dict(arrowstyle='<->', color='red', lw=2))
223
ax2.text((C_0_demo+C_alpha_demo)/2, -0.3, f'{C_alpha_demo-C_0_demo}', ha='center', fontsize=12, color='red')
224
225
W_L_calc = (C_0_demo - C_L_demo)/(C_alpha_demo - C_L_demo) * 100
226
W_alpha_calc = (C_alpha_demo - C_0_demo)/(C_alpha_demo - C_L_demo) * 100
227
228
ax2.set_xlim(20, 60)
229
ax2.set_ylim(-0.6, 0.6)
230
ax2.set_xlabel('Composition (wt\\% Ni)')
231
ax2.set_title(f'Lever Rule: $W_L$ = {W_L_calc:.1f}\\%, $W_\\alpha$ = {W_alpha_calc:.1f}\\%')
232
ax2.legend(loc='upper right')
233
ax2.set_yticks([])
234
235
save_fig('lever_rule.pdf')
236
\end{pycode}
237
238
\begin{figure}[H]
239
\centering
240
\includegraphics[width=\textwidth]{lever_rule.pdf}
241
\caption{Lever rule analysis: phase fractions during cooling and graphical representation.}
242
\end{figure}
243
244
\section{Eutectic System}
245
246
A eutectic system has limited solid solubility. The Pb-Sn system is a classic example.
247
248
\begin{pycode}
249
# Pb-Sn eutectic phase diagram
250
x_Sn = np.linspace(0, 100, 500)
251
252
# Key points
253
T_Pb = 327 # Melting point of Pb
254
T_Sn = 232 # Melting point of Sn
255
T_E = 183 # Eutectic temperature
256
x_E = 61.9 # Eutectic composition
257
x_alpha_max = 19 # Max solubility in alpha
258
x_beta_max = 97.5 # Max solubility in beta
259
260
# Liquidus curves
261
T_liq_left = T_Pb - (T_Pb - T_E) * (x_Sn / x_E)**1.2
262
T_liq_right = T_Sn - (T_Sn - T_E) * ((100 - x_Sn) / (100 - x_E))**1.2
263
T_liquidus = np.where(x_Sn <= x_E, T_liq_left, T_liq_right)
264
265
# Solidus curves (solvus)
266
T_sol_alpha = T_E + (T_Pb - T_E) * ((x_alpha_max - x_Sn) / x_alpha_max)**2
267
T_sol_beta = T_E + (T_Sn - T_E) * ((x_Sn - x_beta_max) / (100 - x_beta_max))**2
268
269
fig, ax = plt.subplots(figsize=(10, 8))
270
271
# Liquidus
272
ax.plot(x_Sn, T_liquidus, 'b-', linewidth=2.5, label='Liquidus')
273
274
# Solidus (solvus) lines
275
x_alpha = x_Sn[x_Sn <= x_alpha_max]
276
ax.plot(x_alpha, T_sol_alpha[x_Sn <= x_alpha_max], 'r-', linewidth=2)
277
x_beta = x_Sn[x_Sn >= x_beta_max]
278
ax.plot(x_beta, T_sol_beta[x_Sn >= x_beta_max], 'r-', linewidth=2)
279
280
# Eutectic isotherm
281
ax.plot([x_alpha_max, x_beta_max], [T_E, T_E], 'k-', linewidth=2)
282
283
# Labels for regions
284
ax.text(10, 280, 'L', fontsize=14, fontweight='bold')
285
ax.text(8, 100, '$\\alpha$', fontsize=14, fontweight='bold')
286
ax.text(88, 100, '$\\beta$', fontsize=14, fontweight='bold')
287
ax.text(50, 100, '$\\alpha + \\beta$', fontsize=14, fontweight='bold')
288
ax.text(30, 220, 'L + $\\alpha$', fontsize=12)
289
ax.text(75, 210, 'L + $\\beta$', fontsize=12)
290
291
# Eutectic point
292
ax.plot(x_E, T_E, 'ko', markersize=10)
293
ax.annotate(f'Eutectic\\n({x_E}\\%, {T_E}$^\\circ$C)',
294
(x_E, T_E), xytext=(x_E-20, T_E-40), fontsize=10)
295
296
ax.set_xlabel('Composition (wt\\% Sn)')
297
ax.set_ylabel('Temperature ($^\\circ$C)')
298
ax.set_title('Pb-Sn Eutectic Phase Diagram')
299
ax.set_xlim(0, 100)
300
ax.set_ylim(0, 350)
301
ax.grid(True, alpha=0.3)
302
303
save_fig('eutectic_diagram.pdf')
304
\end{pycode}
305
306
\begin{figure}[H]
307
\centering
308
\includegraphics[width=\textwidth]{eutectic_diagram.pdf}
309
\caption{Pb-Sn eutectic phase diagram showing liquid, solid, and two-phase regions.}
310
\end{figure}
311
312
\section{Cooling Curves}
313
314
Cooling curves reveal phase transformations through thermal arrests.
315
316
\begin{pycode}
317
# Cooling curves for different compositions
318
compositions = [10, 40, 61.9, 80] # wt% Sn
319
colors = ['blue', 'green', 'red', 'purple']
320
321
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
322
323
for comp, color, ax in zip(compositions, colors, axes.flat):
324
# Generate cooling curve
325
time = np.linspace(0, 600, 1000)
326
327
if comp < x_E: # Hypoeutectic
328
T_start = 350
329
T_liq = T_Pb - (T_Pb - T_E) * (comp / x_E)**1.2
330
331
# Cooling stages
332
t1 = 100 # Start of solidification
333
t2 = 300 # End of primary solidification
334
t3 = 400 # End of eutectic solidification
335
336
T = np.piecewise(time,
337
[time < t1, (time >= t1) & (time < t2), (time >= t2) & (time < t3), time >= t3],
338
[lambda t: T_start - (T_start - T_liq) * t/t1,
339
lambda t: T_liq - (T_liq - T_E) * (t - t1)/(t2 - t1) * 0.8,
340
T_E,
341
lambda t: T_E - (t - t3) * 0.3])
342
343
elif comp > x_E: # Hypereutectic
344
T_start = 280
345
T_liq = T_Sn - (T_Sn - T_E) * ((100 - comp) / (100 - x_E))**1.2
346
347
t1 = 80
348
t2 = 250
349
t3 = 350
350
351
T = np.piecewise(time,
352
[time < t1, (time >= t1) & (time < t2), (time >= t2) & (time < t3), time >= t3],
353
[lambda t: T_start - (T_start - T_liq) * t/t1,
354
lambda t: T_liq - (T_liq - T_E) * (t - t1)/(t2 - t1) * 0.8,
355
T_E,
356
lambda t: T_E - (t - t3) * 0.3])
357
358
else: # Eutectic
359
T_start = 220
360
t1 = 50
361
t2 = 300
362
363
T = np.piecewise(time,
364
[time < t1, (time >= t1) & (time < t2), time >= t2],
365
[lambda t: T_start - (T_start - T_E) * t/t1,
366
T_E,
367
lambda t: T_E - (t - t2) * 0.3])
368
369
ax.plot(time, T, color=color, linewidth=2)
370
ax.axhline(T_E, color='k', linestyle='--', alpha=0.5)
371
ax.set_xlabel('Time (s)')
372
ax.set_ylabel('Temperature ($^\\circ$C)')
373
ax.set_title(f'{comp}\\% Sn')
374
ax.grid(True, alpha=0.3)
375
376
# Annotate thermal arrests
377
if comp == 61.9:
378
ax.annotate('Eutectic arrest', (175, T_E), xytext=(300, T_E+30),
379
arrowprops=dict(arrowstyle='->', color='black'))
380
381
plt.suptitle('Cooling Curves for Pb-Sn Alloys', fontsize=14, y=1.02)
382
plt.tight_layout()
383
save_fig('cooling_curves.pdf')
384
\end{pycode}
385
386
\begin{figure}[H]
387
\centering
388
\includegraphics[width=\textwidth]{cooling_curves.pdf}
389
\caption{Cooling curves for hypoeutectic (10\%, 40\%), eutectic (61.9\%), and hypereutectic (80\%) Pb-Sn alloys.}
390
\end{figure}
391
392
\section{Microstructure Evolution}
393
394
\begin{pycode}
395
# Microstructure composition analysis
396
# For 40 wt% Sn alloy at different stages
397
398
C_0 = 40 # Overall composition
399
stages = ['Just below liquidus', 'Above eutectic', 'Below eutectic']
400
T_stages = [260, 190, 100]
401
402
fig, axes = plt.subplots(1, 3, figsize=(14, 4))
403
404
for ax, stage, T in zip(axes, stages, T_stages):
405
if T > T_E:
406
# Two-phase: L + alpha
407
W_alpha = 60 # Approximate
408
W_L = 40
409
sizes = [W_alpha, W_L]
410
labels = ['$\\alpha$', 'L']
411
colors_pie = ['lightblue', 'yellow']
412
else:
413
# Three phases present (but at equilibrium: alpha + beta)
414
# Primary alpha + eutectic mixture
415
W_primary = 55
416
W_eutectic = 45
417
sizes = [W_primary, W_eutectic]
418
labels = ['Primary $\\alpha$', 'Eutectic ($\\alpha + \\beta$)']
419
colors_pie = ['lightblue', 'lightgreen']
420
421
ax.pie(sizes, labels=labels, colors=colors_pie, autopct='%1.1f%%',
422
startangle=90)
423
ax.set_title(f'{stage}\\n(T = {T}$^\\circ$C)')
424
425
plt.suptitle(f'Microstructure Evolution for {C_0}\\% Sn Alloy', fontsize=12)
426
plt.tight_layout()
427
save_fig('microstructure_evolution.pdf')
428
\end{pycode}
429
430
\begin{figure}[H]
431
\centering
432
\includegraphics[width=\textwidth]{microstructure_evolution.pdf}
433
\caption{Microstructure evolution during cooling of 40\% Sn alloy.}
434
\end{figure}
435
436
\section{Phase Fraction Calculations}
437
438
\begin{pycode}
439
# Complete phase fraction analysis at room temperature
440
compositions = np.linspace(0, 100, 100)
441
T_room = 25
442
443
# At room temperature: alpha + beta region
444
# Alpha: ~2% Sn, Beta: ~99% Sn
445
C_alpha = 2
446
C_beta = 99
447
448
W_alpha_arr = (C_beta - compositions) / (C_beta - C_alpha) * 100
449
W_beta_arr = (compositions - C_alpha) / (C_beta - C_alpha) * 100
450
451
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
452
453
ax1.plot(compositions, W_alpha_arr, 'b-', linewidth=2, label='$\\alpha$ phase')
454
ax1.plot(compositions, W_beta_arr, 'r-', linewidth=2, label='$\\beta$ phase')
455
ax1.axvline(x_E, color='k', linestyle='--', alpha=0.5, label='Eutectic')
456
ax1.set_xlabel('Composition (wt\\% Sn)')
457
ax1.set_ylabel('Phase Fraction (\\%)')
458
ax1.set_title('Equilibrium Phase Fractions at Room Temperature')
459
ax1.legend()
460
ax1.grid(True, alpha=0.3)
461
462
# Primary vs eutectic fractions
463
W_primary_alpha = np.maximum(0, (x_E - compositions) / (x_E - x_alpha_max) * 100)
464
W_primary_beta = np.maximum(0, (compositions - x_E) / (x_beta_max - x_E) * 100)
465
W_eutectic = 100 - W_primary_alpha - W_primary_beta
466
467
ax2.fill_between(compositions, 0, W_primary_alpha, alpha=0.5, label='Primary $\\alpha$')
468
ax2.fill_between(compositions, W_primary_alpha, W_primary_alpha + W_eutectic,
469
alpha=0.5, label='Eutectic')
470
ax2.fill_between(compositions, W_primary_alpha + W_eutectic, 100,
471
alpha=0.5, label='Primary $\\beta$')
472
ax2.set_xlabel('Composition (wt\\% Sn)')
473
ax2.set_ylabel('Microconstituent Fraction (\\%)')
474
ax2.set_title('Microconstituent Fractions')
475
ax2.legend()
476
ax2.grid(True, alpha=0.3)
477
478
plt.tight_layout()
479
save_fig('phase_fractions.pdf')
480
\end{pycode}
481
482
\begin{figure}[H]
483
\centering
484
\includegraphics[width=\textwidth]{phase_fractions.pdf}
485
\caption{Phase fractions and microconstituent analysis for Pb-Sn system.}
486
\end{figure}
487
488
\section{Summary Table}
489
490
\begin{table}[H]
491
\centering
492
\caption{Key Phase Diagram Parameters for Pb-Sn System}
493
\begin{tabular}{lcc}
494
\toprule
495
Parameter & Value & Units \\
496
\midrule
497
Eutectic temperature & \py{f"{T_E}"} & $^{\circ}$C \\
498
Eutectic composition & \py{f"{x_E}"} & wt\% Sn \\
499
Max solubility in $\alpha$ & \py{f"{x_alpha_max}"} & wt\% Sn \\
500
Max solubility in $\beta$ & \py{f"{x_beta_max}"} & wt\% Sn \\
501
Melting point of Pb & \py{f"{T_Pb}"} & $^{\circ}$C \\
502
Melting point of Sn & \py{f"{T_Sn}"} & $^{\circ}$C \\
503
\bottomrule
504
\end{tabular}
505
\end{table}
506
507
\section{Conclusions}
508
509
This analysis demonstrates key aspects of binary phase diagrams:
510
\begin{enumerate}
511
\item The Gibbs phase rule determines degrees of freedom in multi-phase systems
512
\item Isomorphous systems show complete solid solubility with smooth liquidus/solidus curves
513
\item The lever rule enables quantitative calculation of phase fractions
514
\item Eutectic systems exhibit invariant reactions at fixed temperature and composition
515
\item Cooling curves reveal thermal arrests during phase transformations
516
\item Microstructure depends on both equilibrium phases and solidification path
517
\end{enumerate}
518
519
\end{document}
520
521