msspec_python3/tests/sprkkr/STO/STO.py

160 lines
6.0 KiB
Python

# coding: utf8
# vim: set et sw=4 ts=4 fdm=indent nu cc=+1:
from ase.lattice.tetragonal import SimpleTetragonalFactory
from ase.visualize import view
from ase.spacegroup import get_spacegroup
from sprkkr.calculator import SPRKKR
from msspec.calculator import MSSPEC, XRaySource
from msspec.utils import *
import numpy as np
import logging
import sys
import os
import shutil
import glob
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
# Define a Perovskite Factory class
class PerovskiteFactory(SimpleTetragonalFactory):
bravais_basis = [[0, 0, 0.0], [0.5, 0.5, 0.5],[0.5, 0, 0], [0, 0.5, 0],
[0.0, 0.0, 0.5]]
element_basis = (0, 1, 2, 2, 2)
ABO3 = Perovskite = PerovskiteFactory()
# Generate the base STO cell
a0 = 3.905
STO = Perovskite(('Sr', 'Ti', 'O'),
latticeconstant={'a': a0, 'c/a': 1.},
size=(1,1,1))
prefix = "SrTiO3"
if 'view' in sys.argv:
view(STO)
# ########## SPRKKR part
if 'sprkkr' in sys.argv:
# create a SPRKKR calculator
calc = SPRKKR(label=f"{prefix}/{prefix}")
# attach the atoms to the calculator object
calc.set_atoms(STO)
# Here is how to modify input file
# calc.input.control_section.set(DATASET="Fe", ADSI="SCF", POTFIL="Fe.pot")
# calc.input.tau_section.set(nktab=250)
# launch kkrscf
calc.get_potential_energy()
# calc2 = SPRKKR(label="Fe/Fe", task="phagen")
# calc2.set_atoms(Fe)
# calc2.input.control_section.set(POTFIL="Fe.pot_new")
# calc2.phagen()
#
# EXPORT POTENTIAL FOR PHAGEN
#
#change task and command
calc.set_command('PHAGEN')
# Change output file
calc.set_outfile(f"{prefix}_phagen.out")
#to change task we need to replace input file tempate
calc.set_inpfile(f"{prefix}_phagen.inp")
calc.input.control_section.set(DATASET="PHAGEN", ADSI="PHAGEN")
#set potetential file to converged potential
conv_potfile=os.path.join(calc.potfile+'_new')
calc.set_potfile(conv_potfile)
#run given task
calc.phagen()
# ######### MsSpec part
if 'msspec' in sys.argv:
###########################################################################
# Build the SrTiO3 cluster #
###########################################################################
# We start by loading the potential since it updates info in the STO cell
pot = SPRKKRPotential(STO, f"{prefix}/{prefix}.pot_new",
*glob.glob(f"{prefix}/*PHAGEN.pot"))
# tag each atom in the STO object to easily set the emitter in the
# hemispherical_cluster function
[atom.set('tag', ('Sr', 'Ti', 'O').index(atom.symbol)) for atom in STO]
# Create a hemispherical cluster centered on a Ti emitter from the
# STO primitive cell used in the SPRKKR step.
# For this example we use 4 planes and the Ti emitter (tag #1) is
# located in the 2nd plane (numbering starts at 0)
cluster = hemispherical_cluster(STO,
planes=4,
emitter_plane=1, emitter_tag=1)
# The created cluster is centered on the emitter atom, so defining
# the absorber attribute is straightforward:
cluster.absorber = get_atom_index(cluster, 0, 0, 0)
###########################################################################
# Set up the PhotoElectron Diffraction calculator #
###########################################################################
# Create the calculator
calc = MSSPEC(spectroscopy='PED', algorithm='expansion', folder='PED')
# minimalistic set of parameter for XPD scan
calc.set_atoms(cluster)
calc.calculation_parameters.scattering_order = 2
# We need to impose a maximum number of tl to use because there is still
# a memory bug that I need to investigate. Anyway, usually 25 is not that
# bad for the kind of atoms and the photon energy of lab sources...
calc.tmatrix_parameters.lmax_mode = 'imposed'
calc.tmatrix_parameters.lmaxt = 25
data = None
for source_energy in np.arange(500., 1501., 100.):
calc.source_parameters.energy = source_energy
# Run a polar scan with the default MuffinTin potential for Ti(2p3/2)
calc.tmatrix_parameters.potential = 'muffin_tin'
data = calc.get_theta_scan(level='2p3/2', data=data)
# Now we use the previously generated SPRKKR potential and run the same
# calculation
calc.tmatrix_parameters.potential = pot
data = calc.get_theta_scan(level='2p3/2', data=data)
# To better see the differences, plot the normalized signal on the
# same graph
# add a new dataset for storing normalized values
dset = data.add_dset(f"comparison at {source_energy} eV")
# make a copy of previous scans values
theta, muffintin_cs, sprkkr_cs = (data[-3].theta.copy(),
data[-3].cross_section.copy(),
data[-2].cross_section.copy())
# divide by the max
sprkkr_cs /= sprkkr_cs.max()
muffintin_cs /= muffintin_cs.max()
# add a new dataset with those values
dset.add_columns(theta=theta, sprkkr=sprkkr_cs, muffintin=muffintin_cs)
# add a view for this dataset
view = dset.add_view('Comparison',
title=(f'Comparison of XPD polar scans for '
r'Ti(2p3/2) at $h\nu$ = {:.0f} eV'.format(
source_energy)),
xlabel=r'$\Theta (\degree$)',
ylabel='Normalized Signal (a.u.)')
view.select('theta', 'sprkkr', legend='With SPRKKR potential')
view.select('theta', 'muffintin', legend='With internal MT potential')
view.set_plot_options(autoscale=True)
# Pop up the final result
data.view()
if len(sys.argv) <= 1:
print("Please specify either 'sprkkr', 'msspec' keywords or both "
"of them on the command line")