In [1]:
import numpy as np
import escape as esc

esc.require("0.9.8")
Loading material database from C:\dev\escape-core\python\src\escape\scattering\..\data\mdb\materials.db

Binary Alloy HRXRD: In(x)Ga(1-x)As on GaAs¶

This notebook demonstrates HRXRD simulation of a binary alloy epilayer In(x)Ga(1-x)As grown pseudomorphically on a GaAs substrate.

Physical model¶

The alloy lattice parameter follows Vegard's law:

$a(x) = (1-x)\,a_{\text{GaAs}} + x\,a_{\text{InAs}}$

For a pseudomorphic (fully strained, R=0) layer, the in-plane lattice matches the substrate, and the out-of-plane lattice is distorted by the Poisson ratio:

$a_\parallel = a_{\text{sub}}$

$\varepsilon_\parallel = (a_\parallel - a_{\text{bulk}}) / a_{\text{bulk}}$

$c_\perp = c_{\text{bulk}}\,(1 - 2\,\nu\,\varepsilon_\parallel)$

where $\nu = C_{12}/C_{11}$ is the Poisson ratio.

The pipeline is:

  1. alloy_unitcell -- Vegard interpolation of lattice parameters
  2. epitaxial_unitcell -- misfit strain + relaxation + Poisson distortion
  3. crystal with MDB -- compute SLD from material database

References¶

  • Vegard, L. (1921). Z. Physik 5, 17-26.
  • Stepanov et al., Phys. Rev. B 57, 4829-4841 (1998).

1. Define parameters¶

The In composition x, relaxation R, Poisson ratio, layer thickness, and roughness are all fittable parameters.

In [2]:
src = esc.xrays(1.540562, units="angstrom")

x_In = esc.par("x(In)", 0.2, userlim=[0, 1])
R = esc.par("Relaxation", 0.0, userlim=[0, 1], fixed=True)
nu = esc.par("C12/C11", 0.453, fixed=True)

layer_thkn = esc.par("InGaAs Thkn", 200.0, units="A")
layer_rough = esc.par("InGaAs RMS", 2.0, units="A")
sub_rough = esc.par("Sub RMS", 1.0, units="A")

2. Build alloy unit cell and epitaxial strain¶

First create endpoint unit cells for GaAs and InAs, then use alloy_unitcell to interpolate by composition and epitaxial_unitcell to apply substrate constraint.

In [3]:
gaas_ucell = esc.unitcell(5.6532, 5.6532, 5.6532, 90, 90, 90)
inas_ucell = esc.unitcell(6.0583, 6.0583, 6.0583, 90, 90, 90)
sub_ucell  = esc.unitcell(5.6532, 5.6532, 5.6532, 90, 90, 90)

alloy_ucell = esc.alloy_unitcell(x_In, gaas_ucell, inas_ucell)

epi_ucell = esc.epitaxial_unitcell(alloy_ucell, sub_ucell, R, nu,
                                   name="InGaAs epi")

print("Alloy unit cell parameters:", [p.name for p in alloy_ucell.parameters])
print("Epitaxial unit cell parameters:", [p.name for p in epi_ucell.parameters])
Alloy unit cell parameters: ['x(In)']
Epitaxial unit cell parameters: ['x(In)', 'Relaxation', 'C12/C11']

3. Create materials and sample¶

The layer material uses the strained alloy unit cell. The substrate uses the unstrained GaAs unit cell. Both use MDB crystal records for SLD computation.

In [4]:
layer_mat = esc.crystal(mid="GaAs", density="mdb", ucell=epi_ucell)
sub_mat   = esc.crystal(mid="GaAs", density="mdb", ucell=sub_ucell)

layer = esc.layer(material=layer_mat, thkn=layer_thkn, rough=layer_rough)
substrate = esc.substrate(material=sub_mat, rough=sub_rough)

sample = esc.multilayer(frgr=esc.air(), bkgr=substrate)
stack = esc.layer_stack(repeat=1)
stack.add(layer)
sample.add(stack)

p1 = sample.show(source=src, profile="sld0re")
p2 = sample.show(source=src, profile="sld0im")
esc.show(p1, p2)
Out[4]:
MultiObjectLayout(children=(HTML(value='', layout=Layout(grid_area='footer')), ParametersPanel(children=(Indep…

4. Simulate HRXRD (004) rocking curve¶

Scan around the GaAs (004) Bragg peak. The alloy peak appears at a lower angle (larger d-spacing) due to the larger In content.

In [5]:
K0 = 2.0 * np.pi / src.wavelength
theta = np.linspace(32.0, 34.0, 1000)
p0_vals = K0 * np.sin(np.deg2rad(theta))

p0 = esc.var("p0")
hrxrd = esc.spechrxrd(p0, sample, h=0, k=0, l=4, beta=1.0,
                      formalism="2x2", source=src, name="InGaAs/GaAs HRXRD")

hrxrd.show(coordinates=p0_vals).config(ylog=True, xlabel="Kz [1/A]",
                                       ylabel="Intensity")
Out[5]:
FunctorObjectLayout(children=(HTML(value='', layout=Layout(grid_area='footer')), ParametersPanel(children=(Ind…