2021-09-24 16:13:14 +02:00
|
|
|
# coding: utf8
|
|
|
|
|
|
|
|
from ase.build import bulk
|
|
|
|
import numpy as np
|
|
|
|
from msspec.calculator import MSSPEC, XRaySource
|
|
|
|
from msspec.utils import hemispherical_cluster, get_atom_index
|
|
|
|
|
|
|
|
|
|
|
|
def create_clusters(nplanes=3):
|
|
|
|
copper = bulk('Cu', a=3.6, cubic=True)
|
|
|
|
clusters = []
|
|
|
|
for emitter_plane in range(nplanes):
|
|
|
|
cluster = hemispherical_cluster(copper,
|
|
|
|
emitter_plane=emitter_plane,
|
|
|
|
planes=emitter_plane+2,
|
|
|
|
shape='cylindrical')
|
|
|
|
cluster.absorber = get_atom_index(cluster, 0, 0, 0)
|
|
|
|
cluster.info.update({
|
|
|
|
'emitter_plane': emitter_plane,
|
|
|
|
})
|
|
|
|
clusters.append(cluster)
|
|
|
|
return clusters
|
|
|
|
|
|
|
|
def compute(clusters, all_theta=[45., 83.],
|
|
|
|
all_T=np.arange(300., 1000., 400.)):
|
|
|
|
data = None
|
|
|
|
for ic, cluster in enumerate(clusters):
|
|
|
|
# Retrieve info from cluster object
|
|
|
|
plane = cluster.info['emitter_plane']
|
|
|
|
|
|
|
|
calc = MSSPEC(spectroscopy='PED', algorithm='expansion')
|
|
|
|
calc.source_parameters.energy = XRaySource.AL_KALPHA
|
|
|
|
calc.muffintin_parameters.interstitial_potential = 14.1
|
|
|
|
|
|
|
|
calc.calculation_parameters.vibrational_damping = 'averaged_tl'
|
|
|
|
calc.calculation_parameters.use_debye_model = True
|
|
|
|
calc.calculation_parameters.debye_temperature = 343
|
|
|
|
calc.calculation_parameters.vibration_scaling = 1.2
|
|
|
|
|
|
|
|
calc.detector_parameters.average_sampling = 'high'
|
|
|
|
calc.detector_parameters.angular_acceptance = 5.7
|
|
|
|
|
|
|
|
for atom in cluster:
|
|
|
|
atom.set('forward_angle', 30)
|
|
|
|
atom.set('backward_angle', 30)
|
|
|
|
filters = ['forward_scattering', 'backward_scattering']
|
|
|
|
calc.calculation_parameters.path_filtering = filters
|
|
|
|
|
|
|
|
calc.calculation_parameters.RA_cutoff = 2
|
|
|
|
|
|
|
|
for T in all_T:
|
|
|
|
for theta in all_theta:
|
|
|
|
calc.calculation_parameters.temperature = T
|
|
|
|
calc.calculation_parameters.scattering_order = min(1 + plane, 3)
|
|
|
|
calc.set_atoms(cluster)
|
|
|
|
data = calc.get_phi_scan(level='2p3/2', theta=theta,
|
|
|
|
phi=np.linspace(0, 100),
|
|
|
|
kinetic_energy=560, data=data)
|
|
|
|
dset = data[-1]
|
|
|
|
dset.title = "plane #{:d}, T={:f}K, theta={:f}°".format(plane,
|
|
|
|
T,
|
|
|
|
theta)
|
|
|
|
|
|
|
|
dset.add_parameter(group='misc', name='plane', value=plane, unit='')
|
|
|
|
dset.add_parameter(group='misc', name='T', value=T, unit='')
|
|
|
|
dset.add_parameter(group='misc', name='theta', value=theta, unit='')
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
|
|
def analysis(data):
|
|
|
|
all_plane = []
|
|
|
|
all_T = []
|
|
|
|
all_theta = []
|
|
|
|
for dset in data:
|
|
|
|
plane = dset.get_parameter('misc', 'plane')['value']
|
|
|
|
T = dset.get_parameter('misc', 'T')['value']
|
|
|
|
theta = dset.get_parameter('misc', 'theta')['value']
|
|
|
|
cs = dset.cross_section.copy()
|
|
|
|
phi = dset.phi.copy()
|
|
|
|
|
|
|
|
if plane not in all_plane: all_plane.append(plane)
|
|
|
|
if T not in all_T: all_T.append(T)
|
|
|
|
if theta not in all_theta: all_theta.append(theta)
|
|
|
|
|
|
|
|
def get_anisotropy(theta, T):
|
|
|
|
cs = None
|
|
|
|
for dset in data:
|
|
|
|
try:
|
|
|
|
_T = dset.get_parameter('misc', 'T')['value']
|
|
|
|
_theta = dset.get_parameter('misc', 'theta')['value']
|
|
|
|
_cs = dset.cross_section.copy()
|
|
|
|
phi = dset.phi.copy()
|
|
|
|
except:
|
|
|
|
continue
|
|
|
|
if _theta == theta and _T == T:
|
|
|
|
try:
|
|
|
|
cs += _cs
|
|
|
|
except:
|
|
|
|
cs = _cs
|
|
|
|
Imax = np.max(cs)
|
|
|
|
Imin = np.min(cs)
|
|
|
|
return (Imax - Imin)/Imax
|
|
|
|
|
|
|
|
# create a substrate dataset for each T and theta
|
|
|
|
anisotropy_dset = data.add_dset("all")
|
|
|
|
anisotropy_view = anisotropy_dset.add_view('Anisotropies',
|
|
|
|
title='Relative anisotropies for Cu(2p)',
|
|
|
|
marker='o',
|
|
|
|
xlabel='T (K)',
|
|
|
|
ylabel=r'$\frac{\Delta I / I_{max}(T)}{\Delta I_{300}'
|
|
|
|
r'/ I_{max}(300)} (\%)$')
|
|
|
|
|
|
|
|
for theta in all_theta:
|
|
|
|
for T in all_T:
|
|
|
|
A = get_anisotropy(theta, T)
|
|
|
|
A0 = get_anisotropy(theta, np.min(all_T))
|
|
|
|
|
|
|
|
anisotropy_dset.add_row(temperature=T, theta=theta, anisotropy=A/A0)
|
|
|
|
|
|
|
|
anisotropy_view.select('temperature', 'anisotropy',
|
|
|
|
where='theta == {:f}'.format(theta),
|
|
|
|
legend=r'$\theta = {:.0f} \degree$'.format(theta))
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
|
|
clusters = create_clusters()
|
|
|
|
data = compute(clusters)
|
|
|
|
data = analysis(data)
|
|
|
|
data.view()
|