msspec_python3/doc/source/tutorials/temperature/Cu_temperature.py

130 lines
4.8 KiB
Python

# 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()