## Name

InitialSpin — Class for representing an initial spin configuration.

## Synopsis

Namespace: NanoLanguage
InitialSpin(scaled_spins)

## Description

The constructor of InitialSpin.

### InitialSpin Arguments

scaled_spins

The initial scaled spin for each atom should be given as a number between -1 and 1 corresponding to the net spin-polarization in fractions of the atomic polarization according to Hund's rule.

Type: A sequence of numbers with the same length as the number of atoms in the system; or a list of tuples with atom indices and corresponding scaled spin values; or a list of tuples with element and scaled spin value; or a combination of the latter two. For noncollinear spin systems the tuple has four numbers, atom index, scaled spin, theta, phi, where the latter are physical spherical coordinates in units of Degree or Radians.

Default: 1.0 for each atom.

### Usage Examples

There are two basic ways to specify the initial spins of the atoms.

1. Using a simple list. In this case, scaled_spins is a list containing the initial scaled spin for each atom, i.e. the number of entries in the list must be equal to the number of atoms in the system (in the central region for DeviceConfigurations).

Example: Set initial spin 1, -0.5, 1 on the first three atoms, 0 for the rest (the configuration contains 50 atoms).

bulk_configuration.setCalculator(
calculator = LCAOCalculator(),
initial_spin = InitialSpin(scaled_spins=[1.,-0.5,1.]+[0.,]*47)
)
2. Identify atoms, or groups of atoms, and set their initial spin individually. In this case, scaled_spins is a list of tuples, each with two elements. The first entry in the tuple can be an integer, to select an individual atom, or an element (like Carbon), to select all atoms of a certain element. The second entry is the initial scaled spin to set for the selected atoms.

Example: The previous example may be specified the following way:

bulk_configuration.setCalculator(
calculator = LCAOCalculator(),
initial_spin = InitialSpin(scaled_spins=[(0,1.),(1,-0.5),(2,1.)])
)

Set the spin 1 on Iron atoms, except for atoms with index 3 and 7.

bulk_configuration.setCalculator(
calculator = LCAOCalculator(),
initial_spin = InitialSpin(scaled_spins=[(Iron,1.),(3,-1), (7,-1)])
)
• Later entries in the list override earlier ones.
• The initial scaled spin is set to 1.0 for atoms for which another value is not specified.
• The sign (positive or negative) of the specified initial spin determines whether the system has a net surplus of spin-up or spin-down electrons.
3. For noncollinear spin you may specify the spin direction in physical spherical coordinates , where is the angle with the z axis, and the polar angle in the x-y plane relative to the x-axis. The collinear case is Radians or Radians.

bulk_configuration.setCalculator(
calculator = LCAOCalculator(),
(3,    0.8,270*Degrees, 216*Degrees)])
)

Also see RandomSpin for an alternative way to set the initial spin.

### Notes

The simplest way to obtain a spin-polarized calculation is to use InitialSpin(), i.e. without any parameters, which means that the initial scaled spin is set to 1.0 for all atoms. This is usually the safest way to obtain good convergence in spin-polarized molecular and bulk systems. In spin-polarized two-probe systems, however, a more careful analysis is often needed in order to obtain reliable convergence. This will be discussed below.

The initial scaled spin for each atom specifies the degree of polarization for unpaired electrons (either spin-up or spin-down) within a given valence electron shell. To understand this properly, it is best to consider a specific example.

The initial spins for the different atoms in a configuration are independent of each other, so without loss of generality we can limit the discussion to one atom. Let us introduce the symbol to denote the initial scaled spin for that atom.

For definiteness, let us look at bulk iron, which has a total of 8 valence electrons (4s23d6).

How should these electrons be distributed with respect to spin in a spin-polarized calculation? In the simplest picture, we start by filling all the available spin-up states, and when they have been filled we add the remaining electrons into spin-down states. The resulting occupations are shown in Table 24 (note that the 4s orbitals (both up and down) are filled before the 3d orbitals).

Table 24: Iron in the maximum spin configuration, i.e. .

4s   3d
Spin-up
Spin-down

This configuration corresponds to an initial scaled spin of (or -1, if we reverse the roles of spin-up and spin-down). For obvious reasons, we will refer to this configuration as the maximum spin configuration.

Let us define some symbols for reference. Let be the total population of shell (4s and 3d, for iron) in the maximum spin configuration, where denotes the spin. We also define the maximum spin polarization for each shell,

which thus is 4 for 3d in the case of iron. For 4s the maximum spin polarization is zero, which means that this shell cannot be initially polarized in the calculations. A spin polarization of the 4s shell can still occur as a result of the self-consistent calculation, but it requires that the total population of the 4s shell is lower than two, and this cannot be used as an initial condition, since the total population of each shell

is fixed and constant in the process of assigning the initial populations.

Now, the initial scaled spin determines the initial spin occupations of the states in shell through the following expression:

As mentioned, the total number of valence electrons in each shell must always be conserved, and this poses a constraint on the initial spin configurations that can be constructed in this way. It can easily be verified, that gives exactly .

Let us see what happens with iron if we set . As mentioned above, only the 3d shell can be polarized initially, and we find

Combined with the constraint , we find

These populations are equally distributed among the five 3d states for each respective spin.

As a further example, had we instead specified we would have obtained a spin-polarized configuration with 4.5 spin-up and 1.5 spin-down electrons on average per unit-cell in the 3d shell.

Now, the parameter initial_spin only affects the initial spin polarization. The converged spin-polarization could very well be different. Let us again study iron as an example.

The script below calculates and prints the converged Mulliken population of a spin-polarized bulk bcc iron system. Since we do not know what value to use for the initial scaled spin, we use 1.0.

bulk_configuration = BulkConfiguration(
bravais_lattice=BodyCenteredCubic(2.8665*Angstrom),
elements=[Iron],
cartesian_coordinates=[[ 0.,  0.,  0.]]*Angstrom
)

numerical_accuracy_parameters = NumericalAccuracyParameters(
k_point_sampling=(10, 10, 10),
)

calculator = LCAOCalculator(
exchange_correlation=LSDA.PZ,
numerical_accuracy_parameters=numerical_accuracy_parameters,
)

initial_spin = InitialSpin(scaled_spins=[1.0])

bulk_configuration.setCalculator(
calculator,
initial_spin=initial_spin,
)

mulliken_population = MullikenPopulation(bulk_configuration)
nlprint(mulliken_population)

If you run the script, it will report the following occupations:

+------------------------------------------------------------------------------+
|                                                                              |
| Mulliken Population Report                                                   |
|                                                                              |
| ---------------------------------------------------------------------------- |
|                        |                                                     |
| Element   Total  Shell | Orbitals                                            |
|                        |                                                     |
|                        |     xy     zy  zz-rr     zx  xx-yy                  |
|   0  Fe   5.108  0.704 |  0.140  0.140  0.142  0.140  0.142                  |
|           2.892  0.497 |  0.111  0.111  0.081  0.111  0.081                  |
|                        |      s                                              |
|                 -0.025 | -0.025                                              |
|                 -0.032 | -0.032                                              |
|                        |     xy     zy  zz-rr     zx  xx-yy                  |
|                  3.641 |  0.694  0.694  0.779  0.694  0.779                  |
|                  1.530 |  0.370  0.370  0.210  0.370  0.210                  |
|                        |      s                                              |
|                  0.317 |  0.317                                              |
|                  0.335 |  0.335                                              |
|                        |      y      z      x                                |
|                  0.471 |  0.157  0.157  0.157                                |
|                  0.562 |  0.187  0.187  0.187                                |
+------------------------------------------------------------------------------+

The number show the Mulliken population of each orbital, for each spin (for each shell, the spin-up populations are listed on the first line, spin-down on the second one).

If you kept an eye on the calculation, you would have noticed that it converged in 18 iterations. The question is now, could we have improved the convergence rate by choosing a different initial spin polarization?

The converged total Mulliken populations (on average per unit cell) for the spin-up and spin-down states are 5.11 and 2.89, respectively. Now these numbers also include the 4s and some 5p electrons (since a DoubleZetaPolarized basis set was used), but the detailed output shows that the spin polarization of these shells is small. Hence, as a reasonable approximation we can use .

Thus, the converged result corresponds to a value of . It can therefore be expected that if we had used this value in the calculation from the beginning, it would have converged faster. This is indeed the case; rerunning the script with the new value of scaled_spins=[0.56], the self-consistent iteration reaches convergence in 10 steps, i.e. we have almost gained a factor 2 in speed!

Note Note how the resulting populations in the two calculations are identical; we are only setting the initial spin; the self-consistent calculation will find the proper solution anyway, provided the initial value is not too far off. In bulk systems this is, as mentioned above, not very critical, but for transport calculations it can sometimes be very hard to reach convergence unless a good initial value is provided. And, under any circumstance, with a good initial we can save a lot of calculation time.

Finally, let us show how to determine the value that should be assigned to in order to generate a given, initial, spin-configuration.

Suppose we wanted to perform a spin-polarized calculation for manganese (7 valence electrons, (4s23d5)) with an initial spin occupation as the one shown in Table 25.

Table 25: Manganese in an electronic configuration with a majority of spin-down electrons.

4s   3d
Spin-up
Spin-down

We can see that , as we have one unpaired spin-down electron. The number of unpaired electrons in the maximum spin configuration for manganese is 5 (all 3d electrons in the spin-up state), and thus we need to set to obtain the desired initial configuration.