Projection

class Projection(spin=None, atoms=None, l_quantum_numbers=None, m_quantum_numbers=None)

Initialize the class by defining the orbitals to include in the projection.

Parameters:
  • spin (None | Spin.Up | Spin.Down | Spin.Sum | Spin.X | Spin.Y | Spin.Z) – Spin components to include in the projection.
    Default: Spin.Sum

  • atoms (None | list of PeriodicTableElement | list of str | list of int | All) – Atoms to include in the projection, defined either by element type, by tag, or by the index of individual atoms.
    Default: All

  • l_quantum_numbers (None | list of int | All) – Shells for the selected atoms to include in the projection.
    Default: All

  • m_quantum_numbers (None | list of int | All) – Orbitals for the selected shells to include in the projection.
    Default: All

atoms()
Returns:

The atoms included in the projection.

Return type:

list of PeriodicTableElement | list of str | list of int | All

lQuantumNumbers()
Returns:

The l-quantum numbers included in the projection.

Return type:

list of int | All

label()

Get the label for this projection.

Returns:

The label used for this projection.

Return type:

str

mQuantumNumbers()
Returns:

The m-quantum numbers included in the projection.

Return type:

list of int | All

setLabel(label)

Set the label for this projection.

Parameters:

label (str) – The new label.

spin()
Returns:

The spin components included in the projection.

Return type:

Spin.Up | Spin.Down | Spin.Sum | Spin.X | Spin.Y | Spin.Z

uniqueString()

Return a unique string representing the state of the object.

Usage Example

The user can declare projection instances and also combine different projections by using the algebraic operations sum, product and difference. The sum will perform the union between the orbital sets, the product the intersection and the difference the disjuntive union. For example

# Define a projection on all orbitals
p1 = Projection()

# Define a projection on s, p orbitals of Oxygen
p2 = Projection(atoms=[Oxygen], l_quantum_numbers=[0, 1])

# Define a projection on Spin Up
p3 = Projection(spin=Spin.Up)

# Define a projection on all orbitals except s and p orbitals of Oxygen
p4 = p1 - p2

# We can define a projection on s and p orbital of Oxygen for Spin Up
# in two equivalent ways.
p5 = p2 * p3

# or
p5 = Projection(atoms=[Oxygen], l_quantum_numbers=[0, 1], spin=Spin.Up)

Note

Projections on the x, y, z Pauli spin matrices with Spin.X, Spin.Y, Spin.Z work differently from other projections; instead of defining a projection subspace based on sets of orbitals, they are operators returning the observable corresponding to spin along each of the three coordinate axes in Euclidean space.

As such, algebraic combinations of projections are undefined when projecting on the Pauli spin matrices. This means that the algebraic combination of two projections is not allowed if either of the two is projecting on one of the Pauli matrices for a particular set of orbitals and the other isn’t projecting on the same Pauli matrix for the same set of orbitals.

For example, the following combinations are allowed:

Projection(spin=Spin.X, atoms=[Silicon]) + Projection(spin=Spin.Y, atoms=[Oxygen])
Projection(spin=Spin.X, atoms=[Silicon]) + Projection(spin=Spin.Z, atoms=[Oxygen])
Projection(spin=Spin.X, atoms=[Silicon]) + Projection(spin=Spin.Up, atoms=[Oxygen])
Projection(spin=Spin.X, atoms=[Silicon]) + Projection(spin=Spin.Down, atoms=[Oxygen])
Projection(spin=Spin.X, atoms=[Silicon]) + Projection(spin=Spin.Sum, atoms=[Oxygen])
Projection(spin=Spin.Up, atoms=[Silicon]) + Projection(spin=Spin.Down, atoms=[Silicon])

These combinations, however, are not allowed:

Projection(spin=Spin.X, atoms=[Silicon]) + Projection(spin=Spin.Y, atoms=[Silicon])
Projection(spin=Spin.X, atoms=[Silicon]) + Projection(spin=Spin.Z, atoms=[Silicon])
Projection(spin=Spin.X, atoms=[Silicon]) + Projection(spin=Spin.Up, atoms=[Silicon])
Projection(spin=Spin.X, atoms=[Silicon]) + Projection(spin=Spin.Down, atoms=[Silicon])
Projection(spin=Spin.X, atoms=[Silicon]) + Projection(spin=Spin.Sum, atoms=[Silicon])

(same for the + and * operators).

Abbreviations

ATK supports a number of keyword which automatically generate a list of projections onto commonly used sets of orbitals. The available keywords are

ProjectOnUpDownSpin

Projections on spin up and spin down

ProjectOnXYZSpin

Projections on the x, y, z Pauli spin matrices

ProjectOnSites

Projections on each available atomic site

ProjectOnTags

Projections on each available tag for atomic sites present in the configuration

ProjectOnElements

Projections on each available element

ProjectOnShellsByElement

Projections on each available shell per each available element

ProjectOnOrbitalsByElement

Projections on each available orbital per each available element

For example, for bulk Gallium Arsenide the keyword ProjectOnElements is equivalent to

projections = [Projection(atoms=[Gallium]), Projection(atoms=[Arsenic])]

Notes

The Projection instances do not contain the list of projection orbitals immediately after declaration. The available information is translated to a set of orbital indexes for a specific configuration only inside analysis objects. The orbital indexes are then used to construct a projection operator, according to the procedure illustrated below.

Definition of the Projection operator

The definition of a projection operator is trivial in an orthogonal basis, where we can define

\[{\hat{\bf P}_M} = \sum_{m \in M} |m \rangle \langle m|\]

This operator is idempotent and hermitian, and the identity operator can be easily expressed as the sum of a projection onto a subspace and the projection onto the complementary subspace:

\[{\hat{\bf I}} = {\hat{\bf P}_M} + {\hat{\bf P}_\bar{M}}\]

For a non-orthogonal basis this definition is not valid anymore and we have to formulate the projection taking into account the overlap between basis functions. In this case it is not possible in general to define a projection operator which is both hermitian and idempotent, and several different definitions are possible. A detailed treatment of this issue and the derivation of some of the formulas used here can be found in [1].

For a non-orthogonal basis the identity operator is written as

\[{\hat{\bf I}} = \sum_{i, j} |i \rangle S^{-1}_{ij} \langle j|\]

where \(S^{-1}\) is the inverse of the overlap matrix, defined as usual by the inner products between basis functions \(S_{ij}=\langle i|j \rangle\). We may then write the projection on a subspace \(M\) as

\[{\hat{\bf P}_M} = \sum_{m \in M, i} |m \rangle S^{-1}_{mi} \langle i|\]

This projection fulfills the condition \({\hat{\bf I}} = {\hat{\bf P}_M} + {\hat{\bf P}_\bar{M}}\). However this operator is not hermitian and we may as well use its adjoint

\[{\hat{\bf P}_M^{\dagger}} = \sum_{m \in M, i} |i \rangle S^{-1}_{mi} \langle m|\]

Also this operator fulfills the condition \({\hat{\bf I}} = {\hat{\bf P}_M ^{\dagger}} + {\hat{\bf P}_\bar{M} ^{\dagger}}\). The identity operator can be decomposed in additional different ways and the choice of the projection is not unique [1]. The advantage of those two definitions is that the projection subspace and its complement are orthogonal. This implies that the sum of the weights associated to a projection and its complement is one by construction. We can as well choose to use a linear combination of the projection operator and its adjoint and define a new projector as \(\frac{1}{2}\left( \hat{\bf P}_M ^{\dagger} + \hat{\bf P}_M \right)\). The matrix representation of such linear combination is given by

\[P _{M} = \frac{1}{2} \left( \tilde{P}_{M}S + S\tilde{P}_{M} \right)\]

\(\tilde{P}_{M}\) is a diagonal matrix such that \(P_{m}=1\) if \(m \in M\) and \(P_{m}=0\) otherwise. This is the matrix representation of the projection implemented in QuantumATK. The same expression can also be derived from the taylor expansion to the first order in \(S\) of the projection operator in the orthogonal representation, after an inverse Löwdin transform [2].