# MagneticAnisotropyEnergy¶

class MagneticAnisotropyEnergy(configuration, filename, object_id, theta_angles=None, phi_angles=None, kpoints=None, projections=None, energy_minimum=None, energy_maximum=None, bands_per_electron=None, initial_spin=None, initial_state=None, log_filename_prefix=None, number_of_processes_per_task=None)

Constructor for the MagneticAnisotropyEnergy object.

Parameters: configuration (BulkConfiguration | MoleculeConfiguration) – The configuration with an attached calculator for which to calculate the projected density of states. The configuration must have an LCAOCalculator attached with a pseudopotential that supports Spin-Orbit coupling. filename (str) – The full or relative filename path the Study object should be saved to. See nlsave(). object_id (str) – The name of the study that the Study object should be saved to within the file. This needs to be a unique name in this file. See nlsave(). theta_angles (PhysicalQuantity of type angle.) – A list with theta angles specifying the spin rotation for the magnetic anisotropy calculations. Default: [0.0, 90.0]*Degrees phi_angles – A list with phi angles specifying the spin rotation for the magnetic anisotropy calculations. Default: 0.0*Degrees kpoints – The k-points for which to calculate the projected density of states. Default: The k-point sampling used for the self-consistent calculation. projections (list of Projection | Projection | ProjectionGenerator) – The projections used for the calculating the weights. Default: ProjectOnSites. energy_minimum (PhysicalQuantity of type energy.) – The smallest energy to consider, relative to the Fermi energy. Default: -1000*eV energy_maximum (PhysicalQuantity of type energy.) – The highest energy to consider, relative to the Fermi energy. Default: 1.0*eV bands_per_electron (float) – The number of bands per electron to include in the projection calculations. The number must be 1.0 or larger. Default: 1.1 initial_spin – The initial spins for the polarized configuration. Default: Maximum spin polarization. initial_state (BulkConfiguration | :class:~.MoleculeConfiguration| None) – The initial state object to be used for the polarized configuration. The initial_state must have a calculator with either polarized or unpolarized exchange-correlation. Default: No initial state. log_filename_prefix (str | LogToStdOut) – Filename prefix for the logging output of magnetic anisotropy energy calculations. If LogToStdOut, all logging will instead be sent to standard output. Default: 'magneticanisotropyenergy_' number_of_processes_per_task (int) – The number of processes that will be used to execute each task. If this value is greater than or equal to the total number of available processes, each single task will be executed collaboratively over all processes. Otherwise, a delegator-worker scheme is used; in this case, one process will be set aside as the delegator, and the remaining ones will be grouped into workers and execute tasks concurrently. Default: All available processes execute each task collaboratively.
addAngles(theta_angles=None, phi_angles=None)

Add a list of theta- and/or phi angles to the MagneticAnisotropyEnergy study. These will be calculated the next time the object is updated.

Parameters: theta_angles (PhysicalQuantity of type angle) – A list with theta angles specifying the spin rotation for the magnetic anisotropy calculations. phi_angles – A list with phi angles specifying the spin rotation for the magnetic anisotropy calculations.
addProjections(projections=None)

Add a list of projection or a projection generator to the MagneticAnisotropyEnergy study. These will be calculated the next time the object is updated.

Parameters: projections (list of Projection | Projection | ProjectionGenerator) – The projections used for the calculating the weights.
bandEnergies(theta, phi)
Parameters: theta (PhysicalQuantity of type angle.) – The theta angle to get the results for. phi (PhysicalQuantity of type angle.) – The phi angle to get the results for. The band energies for the updated spin orbit configuration for specified theta and phi angles. The energies array has dimension (number_number_of_kpoints, number_of_bands). PhysicalQuantity of type energy
bandEnergyVsAngles()

Calculates the summed band energies for all the angles.

Returns: The total magnetic anisotropy energy as function of theta and phi angles. The shape of the array is (n-theta, n-phi), where n-theta is the number of theta angles and n-phi is the number of phi angles. PhysicalQuantity of type energy.
bandsPerElectron()
Returns: The number of bands per electron to include in the projection calculations. float
calculatedPhiAngles()

Retrieve the list of calculated phi angles.

Returns: The list of calculated phi angles. PhysicalQuantity of type angle.
calculatedThetaAngles()

Retrieve the list of calculated theta angles.

Returns: The list of calculated theta angles. PhysicalQuantity of type angle.
calculator()
Returns: The calculator attached to the configuration. LCAOCalculator
energyMaximum()
Returns: The highest energy to consider, relative to the Fermi energy. PhysicalQuantity of type energy.
energyMinimum()
Returns: The smallest energy to consider, relative to the Fermi energy. PhysicalQuantity of type energy.
filename()
Returns: The filename where the study object is stored. str
initialSpin()
Returns: The initial spin used for the polarized calculation. InitialSpin
initialState()
Returns: The initial state used for the polarized calculation. BulkConfiguration | None
kpoints()
Returns: The k-point sampling used for calculating the magnetic anisotropy energy. MonkhorstPackGrid | RegularKpointGrid
logFilenamePrefix()
Returns: The filename prefix for the logging output of the study. str | LogToStdOut
magneticAnisotropyEnergy(theta_0=None, phi_0=None, theta_1=None, phi_1=None, projections=None, energy_minimum=None, energy_maximum=None)

The magnetic anisotropy energy is defined as MAE = E(theta_1, phi_1) - E(theta_0, phi_0).

Parameters: theta_0 (PhysicalQuantity of type angle.) – One of the theta angles to check. Default: The first theta angle. theta_1 (PhysicalQuantity of type angle.) – One of the theta angles to check. Default: The last theta angle. phi_0 (PhysicalQuantity of type angle.) – One of the phi angles to check. Default: The first phi angle. phi_1 (PhysicalQuantity of type angle.) – One of the phi angles to check. Default: The last phi angle. projections (list of Projection | Projection | ProjectionGenerator) – The projections to get the weights for. energy_minimum (PhysicalQuantity of type energy.) – The smallest energy to consider, relative to the Fermi energy. energy_maximum (PhysicalQuantity of type energy.) – The highest energy to consider, relative to the Fermi energy. The total MAE. PhysicalQuantity of type energy.
nlprint(stream=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>)

Print a string containing an ASCII table summarizing the available results for the study.

Parameters: stream (file-like) – The stream to write to. This should be an object that supports strings being written to it using a write method. Default: sys.stdout
numberOfProcessesPerTask()
Returns: The number of processes to be used to execute each task. If None, all available processes should execute each task collaboratively. int | None
objectId()
Returns: The name of the study object in the file. str
phiAngles()
Returns: The phi angles used for the calculated magnetic anisotropy energy. PhysicalQuantity of type angle.
projectedBandEnergyVsAngles(projections=None)

Calculates the projected band energies for all the angles.

Parameters: projections (list of Projection | Projection | ProjectionGenerator) – The projections to get the weights for. The projected magnetic anisotropy energy as function of theta and phi angles. The shape of the array is (number-of-projections, number-of-theta-angles, number-of-phi-angles). PhysicalQuantity of type energy.
projectionWeights(theta, phi, projections=None)
Parameters: theta (PhysicalQuantity of type angle.) – The theta angle to get the results for. phi (PhysicalQuantity of type angle.) – The phi angle to get the results for. projections (list of Projection | Projection | ProjectionGenerator) – The projections to get the weights for. Retrieve the projection weights for the updated spin orbit configuration for specified theta and phi angles. The weights array has dimensions (number_of_projections, number_number_of_kpoints, number_of_bands). PhysicalQuantity of type energy
projections()
Returns: The projections used for the calculated magnetic anisotropy energy. list of Projection | Projection
summedBandEnergies(theta, phi, projections=None, energy_minimum=None, energy_maximum=None)
Parameters: theta (PhysicalQuantity of type angle.) – The theta angle to get the results for. phi (PhysicalQuantity of type angle.) – The phi angle to get the results for. projections (list of Projection | Projection | ProjectionGenerator) – The projections to get the weights for. energy_minimum (PhysicalQuantity of type energy.) – The smallest energy to consider, relative to the Fermi energy. energy_maximum (PhysicalQuantity of type energy.) – The highest energy to consider, relative to the Fermi energy. The total summed band energy and the projected summed band energies. The projected band energies will have the shape (number-of-projections,). PhysicalQuantity of type energy, PhysicalQuantity of type energy.
thetaAngles()
Returns: The theta angles used for the calculated magnetic anisotropy energy. PhysicalQuantity of type angle.
update()

Run the calculations for the study object.

updatedPolarizedConfiguration()

Retrieve the updated polarized configuration

Returns: The optimized device configuration. If not available, returns None. DeviceConfiguration | None
updatedSpinOrbitConfiguration(theta, phi)

Retrieve the updated spin orbit configuration for specified theta and phi angles.

Returns: The optimized device configuration. If not available, returns None. DeviceConfiguration | None

## Notes¶

Note

Study objects behave differently from analysis objects. See the Study object overview for more details.

The MagneticAnisotropyEnergy object can be used to perform a detailed study of the magnetic anisotropy energy, which is defined as the energy difference between two spin orientations:

$MAE = E(\theta_1, \phi_1) - E(\theta_0, \phi_0),$

where the spin orientation is described by the two spherical angles $$\theta$$ and $$\phi$$.

## Force theorem¶

In the MagneticAnisotropyEnergy study object we calculate the MAE using the force theorem, which allows you to evaluate the energy difference using non-self consistent band energies [DKS90]:

$MAE = \sum_i f_i(\theta_1, \phi_1) \epsilon_i(\theta_1, \phi_1) - \sum_i f_i(\theta_0, \phi_0) \epsilon_i(\theta_0, \phi_0),$

where $$f_i(\theta, \phi)$$ is the occupation factor for band i (including both band and k-point index) with the spin orientation $$(\theta, \phi)$$ and $$\epsilon_i(\theta, \phi)$$ is the corresponding band energy.

The work implemented in the study object is the following

1. Perform a self-consistent polarized calculation.
2. For each spin orientation:
1. Make a non-self consistent spin-orbit calculation using the polarized electron density and effective potential, rotated in the desired direction.
2. Using this configuration calculate and sum the band energies according to the formula above.
3. For each band energy (band index and k-point) we potentially also calculate the projection weight using the specified projection scheme. This step allows for a detailed site- and/or orbital compositional analysis.

The use of the force theorem (FT) has been validated in several papers, e.g. [BH09], [BRCA18] against self-consistent calculations of total energies. Using the FT has several advantages over the self-consistent approach:

• It is significantly faster since the self-consistent solution of the spin-orbit calculation is computationally significantly more demanding than the polarized one.
• Often it is harder to achieve good convergence for a spin-orbit calculation than for a polarized one.
• Using the FT approach allows for projection analysis since each band energy has an associated eigenvector that can be projected onto atomic sites or individual orbitals (see below). The projection analysis is often helpful in understanding the physics behind the calculated MAE. An example could be the difference between surface/interface atoms and bulk atoms in the contribution to the MAE in a metallic slab [BairagiPRL2015.]

Note

The calculator must contain a basis/pseudopotential that supports spin-orbit calculations.

## Usage Example¶

This example script shows how to perform a magnetic anisotropy energy calculation of CoPt in the $$L0_1$$ phase

# -*- coding: utf-8 -*-
# -------------------------------------------------------------
# Bulk Configuration
# -------------------------------------------------------------

# Set up lattice
lattice = Triclinic(
3.72663092*Angstrom, 3.81610456*Angstrom, 3.81610456*Angstrom,
90.0*Degrees, 90.0*Degrees, 90.0*Degrees)

# Define elements
elements = [Cobalt, Cobalt, Platinum, Platinum]

# Define coordinates
fractional_coordinates = [[ 0. ,  0. ,  0. ],
[-0. ,  0.5,  0.5],
[ 0.5,  0. ,  0.5],
[ 0.5,  0.5,  0. ]]

# Set up configuration
bulk_configuration = BulkConfiguration(
bravais_lattice=lattice,
elements=elements,
fractional_coordinates=fractional_coordinates
)

# -------------------------------------------------------------
# Calculator
# -------------------------------------------------------------
#----------------------------------------
# Exchange-Correlation
#----------------------------------------
exchange_correlation = SOGGA.PBE

k_point_sampling = MonkhorstPackGrid(
na=25,
nb=25,
nc=25,
force_timereversal=False,
)

numerical_accuracy_parameters = NumericalAccuracyParameters(
occupation_method=ColdSmearing(0.05*eV),
k_point_sampling=k_point_sampling,
density_mesh_cutoff=155.0*Hartree,
)

calculator = LCAOCalculator(
exchange_correlation=exchange_correlation,
numerical_accuracy_parameters=numerical_accuracy_parameters,
)

bulk_configuration.setCalculator(calculator)

# -------------------------------------------------------------
# Magnetic Anisotropy Energy
# -------------------------------------------------------------
# Kpoint sampling
kpoint_grid = MonkhorstPackGrid(
na=35,
nb=35,
nc=35,
)

# File name.
filename = u'CoPt_MAE.hdf5'

magnetic_anisotropy_energy = MagneticAnisotropyEnergy(
configuration=bulk_configuration,
filename=filename,
object_id='magnetic_anisotropy_energy',
theta_angles=numpy.linspace(0, 90, 2)*Degrees,
phi_angles=numpy.linspace(0, 0, 1)*Degrees,
kpoints=kpoint_grid,
projections=ProjectOnSites,
energy_minimum=-1000*eV,
energy_maximum=1*eV,
bands_per_electron=1.1,
log_filename_prefix='magnetic_anisotropy_energy_',
)

magnetic_anisotropy_energy.update()


magnetic_anisotropy_energy.py

Note

In order to get accurate results, a high k-point sampling is needed on the calculator and an even higher sampling on the MagneticAnisotropyEnergy study object. Convergence with respect to k-point sampling should be carefully checked.

## Results¶

The total MAE can be obtained from the method magneticAnisotropyEnergy which returns the total MAE for specified angles and projections. By default:

mae = magnetic_anisotropy_energy.magneticAnisotropyEnergy()


will return the MAE calculated from the first and last angle pairs defined in the construction of the study object.

It is further possible the access the summed band energies (i.e. not band energy difference) from the method summedBandEnergies.

In order to inspect the dependence on the angles it is possible, using the method projectedBandEnergyVsAngles, to obtain the projected band energies for all the considered angles.

After having updated a MagneticAnisotropyEnergy study object, it is possible perform additional calculations for different angles using the addAngles method:

magnetic_anisotropy_energy.addAngles(phi_angles=[22.5, 45.0]*Degrees)
magnetic_anisotropy_energy.update()


By doing so one avoids to redo the self-consistent polarized calculation since this is already stored on the study.

After having updated a MagneticAnisotropyEnergy study object, it is also possible perform additional calculations for different projections using the addProjections method:

magnetic_anisotropy_energy.addProjections(ProjectOnShellsBySite)
magnetic_anisotropy_energy.update()


for projecting on individual shells $$s, p, d,$$ etc. on each atom, or:

magnetic_anisotropy_energy.addProjections(ProjectOnOrbitalsBySite)
magnetic_anisotropy_energy.update()


for projecting on each orbital $$s, p_x, p_y, p_z,$$ etc. on each atom.

## Calculating without projections¶

If one is only interested in the total MAE and not concerned about the atom or orbital projections it is possible, and often significantly faster, to set the projections to NoProjections like:

projections=NoProjection
`

# References¶

 [BRCA18] M. Blanco-Rey, J.I. Cerda, and A. Arnau. Magnetocrystalline anisotropy of fe-based l10 alloys: Validity of approximate methods to treat the spin-orbit interaction. arXiv, pages 1811.12100v1, 2018. URL: http://arxiv.org/abs/1811.12100v1.
 [BH09] Piotr Blonski and Jurgen Hafner. Density-functional theory of the magnetic anisotropy of nanostructures: an assessment of different approximations. Journal of Physics: Condensed Matter, 21(42):426001, 2009. URL: http://stacks.iop.org/0953-8984/21/i=42/a=426001.
 [DKS90] G. H. O. Daalderop, P. J. Kelly, and M. F. H. Schuurmans. First-principles calculation of the magnetocrystalline anisotropy energy of iron, cobalt, and nickel. Phys. Rev. B, 41:11919, 1990. doi:10.1103/PhysRevB.41.11919.