diff --git a/msspecbook/_build/html/Activity02/Activity02.html b/msspecbook/_build/html/Activity02/Activity02.html index 809683b..c03f46a 100644 --- a/msspecbook/_build/html/Activity02/Activity02.html +++ b/msspecbook/_build/html/Activity02/Activity02.html @@ -359,7 +359,7 @@ document.write(`
-

Activity 2: Setting up the “experiment”#

+

Activity 2: Setting up the “experiment”#

To model a spectroscopy experiment, some parameters need to be correctly defined. In MsSpec, parameters are grouped in different categories (detector_parameters, source_parameters, calculation_parameters…). Each category is an attribute of your calculator object and contains different parameters. For example, to define the angle of the incoming light with respect to the sample normal direction, you will use

# (assuming your calculator variable is calc)
diff --git a/msspecbook/_build/html/Activity03/Activity03.html b/msspecbook/_build/html/Activity03/Activity03.html
index 8cb33b6..4fc9033 100644
--- a/msspecbook/_build/html/Activity03/Activity03.html
+++ b/msspecbook/_build/html/Activity03/Activity03.html
@@ -359,7 +359,7 @@ document.write(`
                 
-

Activity 3: Adsorbates and the single scattering approach#

+

Activity 3: Adsorbates and the single scattering approach#

Photoelectron diffraction is widely used to study the adsorption of atoms or molecules on a crystalline surface. Photoelectrons from adsorbates are scattered by the underlying surface, carrying information about the adsorption site, bond length and/or molecule orientation…. Thanks to a simulation, such information becomes quantitative with a high degree of accuracy.

Calculations of the multiple scattering using matrix inversion have the great advantage of being exact, including all scattering paths. On the other hand, memory consumption soon becomes a problem as the kinetic energy and number of atoms to be considered increase. As an approximation, it is possible to only consider a single scattering from the emitter to any atom in the cluster. This approximation is extremely computationally fast and can give satisfactory results for adsorbates. We’ll see later that this approach is rather too simplistic for most cases.

diff --git a/msspecbook/_build/html/Activity08/Activity08.html b/msspecbook/_build/html/Activity08/Activity08.html index 2017d04..27e6f63 100644 --- a/msspecbook/_build/html/Activity08/Activity08.html +++ b/msspecbook/_build/html/Activity08/Activity08.html @@ -57,6 +57,8 @@ + + @@ -317,7 +319,9 @@ document.write(` `); - +
@@ -333,6 +337,14 @@ document.write(`
+
+

Contents

+
+
@@ -344,6 +356,217 @@ document.write(`

Activity 8: Inequivalent emitters and the XPD of a substrate#

+

XPD can be used to study the adsorption of atoms or molecules on surfaces (Activity 3), or atomic substitutions on surfaces (Activity 2). In this case, modeling is relatively straightforward, since only one emitter atom is involved.

+

We have seen from previous examples that, for kinetic energies \(\gtrsim\) 500 eV, the use of Rehr-Albers series expansion and scattering path filtering give access to the intensity of deeper emitter atoms (Activity 7). +This is the key to computing the total photodiffraction signal of a substrate. As emitted photoelectrons originate from highly localized core levels around the atoms, the total signal corresponds to the (incoherent) sum of the intensities of all inequivalent emitters in the probed volume.

+

Let’s take a look at how this is done on the following example.

+
+

The Aluminium Nitride (AlN) polarity#

+

In this example, we will compute polar diagrams of an aluminum nitride substrate.

+

In a work published in 1999, Lebedev et al. demonstrated that Photoelectron diffraction can be used as a non invasive tool to unambiguously state the polarity of an AlN surface. Aluminium nitride cristallizes in an hexagonal cell and the authors experimentally showed that the polarity of the surface can be controlled by the annealing temperature during the growth. Both polarities are sketched in the figure below.

+
+

See also

+

based on this paper from V. Lebedev et al. +J. Cryst. Growth. 207(4) p266-72 (1999)

+
+
+AlN crystal direction + +
+

Fig. 19 AlN hexagonal lattice. Left) N polarity with nitrogen terminated surface and AlN4 tetrahedrons pointing downward. Right) Al polarity with aluminium terminated surface and AlN4 tetrahedrons pointing upward#

+
+
+

The AlN(0001) and (00.-1) faces share the same crystallograpphic symmetry and the Al and N atoms have the same geometrical surrounding differing only in the exchange of Al and N atoms (Fig. 20).

+

It is thus expected that Al(2p) and N(1s) XPD patterns exhibit almost the same features with only small differences due to the contrast between Al and N scattering amplitudes.

+
+AlN crystal direction + +
+

Fig. 20 Side views of N- or Al- terminated surfaces showing nearest neighbours main polar crystallographic directions. The inset shows the experimental Al(2p)/N(1s) ratio versus polar angle for both AlN polarities (taken from Lebedev et al.).#

+
+
+

The strongest differences in photoemission intensities suitable for a quick and unambiguous determination of polarity were found in the (10-10) azimuthal plane at 32° and 59° (polar scans in the inset of Fig. 20).

+

These are the directions of short neighbor distances between the atoms of the same element (32°) and between Al and N atoms (58.5°), respectively.

+
+ +
+

Using the crystal view in Fig. 19 and assuming that we want to compute Al(2p) and N(1s) intensities for emitters located in 3 different planes to get a substrate signal. How many clusters do we need to build ?

+
+
+
+
+AlN number of clusters + +
+

Fig. 21 Number of different clusters to build for Al(2p) and N(1s) in 3 planes#

+
+
+
+
+
+
+ +
+

Download this script and fill in the lines indicated by the comments “FILL HERE”. Run the calculation and check that you are reproducing polar scan of Fig. 20.

+
+
+
+
+AlN results + +
+

Fig. 22 Polar scans in the (10-10) azimuthal plane of AlN for Al polarity (left) and N polarity (right)#

+
+
+
+AlN results + +
+

Fig. 23 Al(2p)/N(1s) intensity ratio for both polarities#

+
+
+

As can be seen in Fig. 23, the peaks at 32° and 58.5° are well reproduced by the calculation for an Al polarity. Some discreapancies arise between the experimental work and this simulation especially for large polar angles. This may be due to a too small cluster in diameter for the deeper emitters.

+
  1#!/usr/bin/env python
+  2# coding: utf8
+  3
+  4from ase.build import bulk
+  5import numpy as np
+  6from msspec.calculator import MSSPEC, XRaySource
+  7from msspec.utils import hemispherical_cluster, get_atom_index
+  8
+  9def create_clusters(nplanes=6):
+ 10    def get_AlN_tags_planes(side, emitter):
+ 11        AlN = bulk('AlN', crystalstructure='wurtzite', a=3.11, c=4.975)
+ 12        [atom.set('tag', i) for i, atom in enumerate(AlN)]
+ 13        if side == 'Al':
+ 14            AlN.rotate([0,0,1],[0,0,-1])
+ 15            Al_planes = range(0, nplanes, 2)
+ 16            N_planes  = range(1, nplanes, 2)
+ 17        else:
+ 18            N_planes  = range(0, nplanes, 2)
+ 19            Al_planes = range(1, nplanes, 2)
+ 20        if emitter == 'Al':
+ 21            tags = [0, 2]
+ 22            planes = Al_planes
+ 23        else:
+ 24           tags = [1, 3]
+ 25           planes = N_planes
+ 26        return AlN, tags, planes
+ 27
+ 28    clusters = []
+ 29    for side in ('Al', 'N'):
+ 30        for emitter in ('Al', 'N'):
+ 31            AlN, tags, planes = get_AlN_tags_planes(side, emitter)
+ 32            for emitter_tag in tags:
+ 33                for emitter_plane in planes:
+ 34                    cluster = hemispherical_cluster(AlN,
+ 35                                                    emitter_tag=emitter_tag,
+ 36                                                    emitter_plane=emitter_plane,
+ 37                                                    planes=emitter_plane+2)
+ 38                    cluster.absorber = get_atom_index(cluster, 0, 0, 0)
+ 39                    cluster.info.update({
+ 40                        'emitter_plane': emitter_plane,
+ 41                        'emitter_tag'  : emitter_tag,
+ 42                        'emitter'      : emitter,
+ 43                        'side'         : side,
+ 44                    })
+ 45                    clusters.append(cluster)
+ 46                    print("Added cluster {}-side, emitter {}(tag {:d}) in "
+ 47                          "plane #{:d}".format(side, emitter, emitter_tag,
+ 48                                               emitter_plane))
+ 49    return clusters
+ 50
+ 51
+ 52def compute(clusters, theta=np.arange(-20., 80., 1.), phi=0.):
+ 53    data = None
+ 54    for ic, cluster in enumerate(clusters):
+ 55        # Retrieve info from cluster object
+ 56        side    = cluster.info['side']
+ 57        emitter = cluster.info['emitter']
+ 58        plane   = cluster.info['emitter_plane']
+ 59        tag     = cluster.info['emitter_tag']
+ 60
+ 61        # Set the level and the kinetic energy
+ 62        if emitter == 'Al':
+ 63            level = '2p'
+ 64            ke    = 1407.
+ 65        elif emitter == 'N':
+ 66            level = '1s'
+ 67            ke    = 1083.
+ 68
+ 69        calc = MSSPEC(spectroscopy='PED', algorithm='expansion')
+ 70
+ 71        calc.source_parameters.energy = XRaySource.AL_KALPHA
+ 72        calc.source_parameters.theta  = -35
+ 73
+ 74        calc.detector_parameters.angular_acceptance = 4.
+ 75        calc.detector_parameters.average_sampling   = 'medium'
+ 76
+ 77        calc.calculation_parameters.scattering_order = max(1, min(4, plane))
+ 78        calc.calculation_parameters.path_filtering  = 'forward_scattering'
+ 79        calc.calculation_parameters.off_cone_events = 1
+ 80        [a.set('forward_angle', 30.) for a in cluster]
+ 81
+ 82        calc.set_atoms(cluster)
+ 83
+ 84        data = calc.get_theta_scan(level=level, theta=theta, phi=phi,
+ 85                                   kinetic_energy=ke, data=data)
+ 86        dset = data[-1]
+ 87        dset.title = "\'{}\' side - {}({}) tag #{:d}, plane #{:d}".format(
+ 88            side, emitter, level, tag, plane)
+ 89
+ 90    return data
+ 91
+ 92
+ 93def analysis(data):
+ 94    tmp_data = {}
+ 95    for dset in data:
+ 96        info = dset.get_cluster().info
+ 97        side = info['side']
+ 98        emitter = info['emitter']
+ 99        try:
+100            key = '{}_{}'.format(side, emitter)
+101            tmp_data[key] += dset.cross_section
+102        except KeyError:
+103            tmp_data[key] = dset.cross_section.copy()
+104
+105    tmp_data['theta']   = dset.theta.copy()
+106    tmp_data['Al_side'] = tmp_data['Al_Al'] / tmp_data['Al_N']
+107    tmp_data['N_side']  = tmp_data['N_Al']  / tmp_data['N_N']
+108
+109    # now add all columns
+110    substrate_dset = data.add_dset('Total substrate signal')
+111    substrate_dset.add_columns(**tmp_data)
+112
+113    view = substrate_dset.add_view('Ratios',
+114                                   title=r'Al(2p)/N(1s) ratios on both polar '
+115                                         r'sides of AlN in the (10$\bar{1}$0) '
+116                                         r'azimuthal plane',
+117                                   xlabel=r'$\Theta (\degree$)',
+118                                   ylabel='Intenisty ratio')
+119    view.select('theta', 'Al_side', legend='Al side',
+120                where="theta >= 0 and theta <=70")
+121    view.select('theta', 'N_side', legend='N side',
+122                where="theta >= 0 and theta <=70")
+123    view.set_plot_options(autoscale=True)
+124
+125    return data
+126
+127
+128clusters = create_clusters()
+129for cluster in clusters:
+130    cluster.edit()
+131exit()
+132data     = compute(clusters)
+133data     = analysis(data)
+134data.view()
+135
+
+
+
+