Topwave

Topwave is composed of the following modules:

fourier_coefficients

topwave.fourier_coefficients.get_intracell_fourier_coefficient(site: PeriodicSite, kpoint: VectorList) ComplexList[source]

Returns the phase factor from different sublattice positions.

Parameters:
  • site (PeriodicSite) – The pymatgen.core.sites.PeriodicSite for which the coefficient is computed.

  • kpoint (VectorList) – The kpoints at which the coefficient is computed.

Returns:

The intracell Fourier coefficient at the given k-point of the site.

Return type:

ComplexList

topwave.fourier_coefficients.get_periodic_fourier_coefficient(coupling: Coupling, kpoint: VectorList) ComplexList[source]

Returns the Fourier coefficient of a coupling to get a Brillouin zone periodic Hamiltonian.

This is the convention of Fourier transform where the positions of the atomic sites within one unit cell are not taken into account. This should be used for Wilson loop calculations. In this convention, the physical representations of point group symmetries have no k-dependence. (CHECK!)

Parameters:
  • coupling (Coupling) – The topwave.coupling.Coupling for which the coefficient is computed.

  • kpoint (VectorList) – The kpoints at which the coefficient is computed.

Returns:

The Fourier coefficient at the given k-point of the coupling.

Return type:

ComplexList

topwave.fourier_coefficients.get_periodic_fourier_derivative(coupling: Coupling, kpoint: VectorList, direction: str) ComplexList[source]

Returns the derivative of the Fourier coefficient w.r.t. a list of crystal momenta.

This is used to compute the element-wise derivatives of the Hamiltonian w.r.t. crystal momentum. These tangent matrices are useful for computing Berry curvatures or transport properties like the Nernst effect.

Parameters:
  • coupling (Coupling) – The topwave.coupling.Coupling for which the derivative is computed.

  • kpoint (VectorList) – The kpoints at which the derivative is computed.

  • direction (str) – Which crystal momentum is used for the derivative. Options are ‘x’, ‘y’ and ‘z’.

Returns:

The derivative at the given k-point of the coupling.

Return type:

ComplexList

model

class topwave.model.Model(structure: Structure, import_site_properties: bool = False)[source]

Base class that is used to build a model.

This is an abstract base class. Use its child classes to instantiate a model.

Examples

Create a cubic lattice of cobalt atoms and space group symmetry P23 (#195) with pymatgen and use it to create a SpinWaveModel.

In [1]: from pymatgen.core.structure import Structure

In [2]: structure = Structure.from_spacegroup(sg=195, lattice=np.eye(3), species=['Co'], coords=[[0, 0, 0]])

In [3]: print(structure)
Full Formula (Co1)
Reduced Formula: Co
abc   :   1.000000   1.000000   1.000000
angles:  90.000000  90.000000  90.000000
pbc   :       True       True       True
Sites (1)
  #  SP      a    b    c
---  ----  ---  ---  ---
  0  Co      0    0    0

In [4]: model = tp.model.SpinWaveModel(structure)
delete_all_couplings() None[source]

Deletes all couplings.

generate_couplings(max_distance: float, space_group: int) None[source]

Generates couplings up to a distance and groups them based on the space group symmetry.

Parameters:
  • max_distance (float) – The distance up to which the couplings are generated.

  • space_group (int) – The international number of the space group (1 to 230) that is used to group the couplings.

Examples

Find and create the nearest-neighbors and group them by space group symmetry P23 (#195).

In [1]: model.generate_couplings(max_distance=1, space_group=195)

In [2]: model.show_couplings()
╒═════════╤══════════════════╤══════════════════════╤════════════╤══════════════════╤═════════════════════╤═════════╤════════════╤═════════╤════════════╤════════════╤═════════════════════╤═════════════════════════════════════════════════════╕
│   index │   symmetry index │ symmetry operation   │   distance │ lattice_vector   │ sublattice_vector   │   site1 │   orbital1 │   site2 │   orbital2 │ strength   │ spin-orbit vector   │ matrix                                              │
╞═════════╪══════════════════╪══════════════════════╪════════════╪══════════════════╪═════════════════════╪═════════╪════════════╪═════════╪════════════╪════════════╪═════════════════════╪═════════════════════════════════════════════════════╡
│       0 │                0 │ x, y, z              │          1 │ [-1.  0.  0.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │ 0j         │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
├─────────┼──────────────────┼──────────────────────┼────────────┼──────────────────┼─────────────────────┼─────────┼────────────┼─────────┼────────────┼────────────┼─────────────────────┼─────────────────────────────────────────────────────┤
│       1 │                0 │ -z, x, -y            │          1 │ [ 0. -1.  0.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │ 0j         │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
├─────────┼──────────────────┼──────────────────────┼────────────┼──────────────────┼─────────────────────┼─────────┼────────────┼─────────┼────────────┼────────────┼─────────────────────┼─────────────────────────────────────────────────────┤
│       2 │                0 │ y, -z, -x            │          1 │ [-0. -0.  1.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │ 0j         │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
╘═════════╧══════════════════╧══════════════════════╧════════════╧══════════════════╧═════════════════════╧═════════╧════════════╧═════════╧════════════╧════════════╧═════════════════════╧═════════════════════════════════════════════════════╛

Onsite (Inter-Orbital) Couplings:
╒═════════╤══════════════════╤══════════════════════╤════════════╤══════════════════╤═════════════════════╤═════════╤════════════╤═════════╤════════════╤════════════╤═════════════════════╤══════════╕
│ index   │ symmetry index   │ symmetry operation   │ distance   │ lattice_vector   │ sublattice_vector   │ site1   │ orbital1   │ site2   │ orbital2   │ strength   │ spin-orbit vector   │ matrix   │
╞═════════╪══════════════════╪══════════════════════╪════════════╪══════════════════╪═════════════════════╪═════════╪════════════╪═════════╪════════════╪════════════╪═════════════════════╪══════════╡
╘═════════╧══════════════════╧══════════════════════╧════════════╧══════════════════╧═════════════════════╧═════════╧════════════╧═════════╧════════════╧════════════╧═════════════════════╧══════════╛
get_couplings(attribute: str, value: int | float) list[Coupling][source]

Return couplings selected by some attribute.

Parameters:
  • attribute (str) –

    The attribute by which the couplings are selected. Options are ‘is_set’, ‘index’,

    ’symmetry_id’, ‘distance’ or ‘lattice_vector’.

  • value (int | float) – The value of the selected attribute.

Returns:

A list that contains the couplings that match the value of the selected attribute.

Return type:

list[Coupling]

Examples

Select one of the couplings based on its index.

In [1]: model.get_couplings('index', 1)
Out[1]: 
[Coupling(index=1, lattice_vector=array([ 0., -1.,  0.]), site1=PeriodicSite: Co (0.0, 0.0, 0.0) [0.0, 0.0, 0.0], orbital1=0, site2=PeriodicSite: Co (0.0, 0.0, 0.0) [0.0, 0.0, 0.0], orbital2=0, symmetry_id=0, symmetry_op=SymmOp(affine_matrix=array([[ 0.,  0., -1.,  0.],
        [ 1.,  0.,  0.,  0.],
        [ 0., -1.,  0.,  0.],
        [ 0.,  0.,  0.,  1.]])), distance=1.0, sublattice_vector=array([0., 0., 0.]), is_onsite=False, is_set=False, matrix=array([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]]), spin_orbit=array([0., 0., 0.]), strength=0j)]

Select all the couplings based on their symmetry.

In [2]: model.get_couplings('symmetry_id', 0)
Out[2]: 
[Coupling(index=0, lattice_vector=array([-1.,  0.,  0.]), site1=PeriodicSite: Co (0.0, 0.0, 0.0) [0.0, 0.0, 0.0], orbital1=0, site2=PeriodicSite: Co (0.0, 0.0, 0.0) [0.0, 0.0, 0.0], orbital2=0, symmetry_id=0, symmetry_op=SymmOp(affine_matrix=array([[1., 0., 0., 0.],
        [0., 1., 0., 0.],
        [0., 0., 1., 0.],
        [0., 0., 0., 1.]])), distance=1.0, sublattice_vector=array([0., 0., 0.]), is_onsite=False, is_set=False, matrix=array([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]]), spin_orbit=array([0., 0., 0.]), strength=0j),
 Coupling(index=1, lattice_vector=array([ 0., -1.,  0.]), site1=PeriodicSite: Co (0.0, 0.0, 0.0) [0.0, 0.0, 0.0], orbital1=0, site2=PeriodicSite: Co (0.0, 0.0, 0.0) [0.0, 0.0, 0.0], orbital2=0, symmetry_id=0, symmetry_op=SymmOp(affine_matrix=array([[ 0.,  0., -1.,  0.],
        [ 1.,  0.,  0.,  0.],
        [ 0., -1.,  0.,  0.],
        [ 0.,  0.,  0.,  1.]])), distance=1.0, sublattice_vector=array([0., 0., 0.]), is_onsite=False, is_set=False, matrix=array([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]]), spin_orbit=array([0., 0., 0.]), strength=0j),
 Coupling(index=2, lattice_vector=array([-0., -0.,  1.]), site1=PeriodicSite: Co (0.0, 0.0, 0.0) [0.0, 0.0, 0.0], orbital1=0, site2=PeriodicSite: Co (0.0, 0.0, 0.0) [0.0, 0.0, 0.0], orbital2=0, symmetry_id=0, symmetry_op=SymmOp(affine_matrix=array([[ 0.,  1.,  0.,  0.],
        [ 0.,  0., -1.,  0.],
        [-1.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  1.]])), distance=1.0, sublattice_vector=array([0., 0., 0.]), is_onsite=False, is_set=False, matrix=array([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]]), spin_orbit=array([0., 0., 0.]), strength=0j)]
get_onsite_couplings() list[Coupling][source]

Returns couplings that connect different orbitals of the same site.

Returns:

A list that contains the couplings that are onsite (inter-orbital).

Return type:

list[Coupling]

get_set_couplings() list[Coupling][source]

Returns couplings that have been assigned some exchange.

Returns:

A list that contains the couplings that were assigned some exchange.

Return type:

list[Coupling]

get_sites(attribute: str, value: int | str | float) list[PeriodicSite][source]
Parameters:
  • attribute (str) – The attribute by which the couplings are selected. Options are ‘index’, ‘onsite_scalar’, ‘layer’ or ‘uc_site_index’.

  • value (int | float) – The value of the selected attribute.

Returns:

A list that contains the sites that match the value of the selected attribute.

Return type:

list[PeriodicSite]

Examples

Select one of the couplings based on its index.

In [1]: model.get_sites('index', 0)
Out[1]: [PeriodicSite: Co (0.0, 0.0, 0.0) [0.0, 0.0, 0.0]]
abstract get_type() str[source]

Returns the type of the model.

invert_coupling(index: int) None[source]

Inverts the orientation of a coupling.

Parameters:

index (int) – The index of the coupling that is inverted.

Examples

The lattice vector that connects a coupling before and after inversion:

In [1]: print(f'R = {model.couplings[0].lattice_vector}')
R = [-1.  0.  0.]

In [2]: model.invert_coupling(0)

In [3]: print(f'R = {model.couplings[0].lattice_vector}')
R = [ 1. -0. -0.]
remove_coupling(attribute_value: int | float, attribute: str = 'index') None[source]

Removes a selection of couplings and reassigns their indices.

Parameters:
  • attribute_value (int | float) – The value of the selected attribute.

  • attribute (str) –

    The attribute by which the couplings are selected. Options are ‘is_set’, ‘index’,

    ’symmetry_id’, ‘distance’ or ‘lattice_vector’.

Examples

We delete something

set_coupling(attribute_value: int | float, strength: float, attribute: str = 'index', overwrite: bool = True) None[source]

Assigns (scalar) hopping/exchange to a selection of couplings.

Parameters:
  • attribute_value (int | float) – The value of the selected attribute.

  • strength (float) – Strength of the hopping/exchange.

  • attribute (str) –

    The attribute by which the couplings are selected. Options are ‘is_set’, ‘index’,

    ’symmetry_id’, ‘distance’ or ‘lattice_vector’.

  • overwrite (bool) – If true, any existing term is overwritten. If false, the term is added. Default is true.

Examples

Assign ferromagnetic exchange with J=1 to all nearest neighbors. See the ‘strength’ column in the output.

In [1]: model.set_coupling(attribute_value=0, strength=1, attribute='symmetry_id')

In [2]: model.show_couplings()
╒═════════╤══════════════════╤══════════════════════╤════════════╤══════════════════╤═════════════════════╤═════════╤════════════╤═════════╤════════════╤════════════╤═════════════════════╤═════════════════════════════════════════════════════╕
│   index │   symmetry index │ symmetry operation   │   distance │ lattice_vector   │ sublattice_vector   │   site1 │   orbital1 │   site2 │   orbital2 │   strength │ spin-orbit vector   │ matrix                                              │
╞═════════╪══════════════════╪══════════════════════╪════════════╪══════════════════╪═════════════════════╪═════════╪════════════╪═════════╪════════════╪════════════╪═════════════════════╪═════════════════════════════════════════════════════╡
│       0 │                0 │ x, y, z              │          1 │ [ 1. -0. -0.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │          1 │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
├─────────┼──────────────────┼──────────────────────┼────────────┼──────────────────┼─────────────────────┼─────────┼────────────┼─────────┼────────────┼────────────┼─────────────────────┼─────────────────────────────────────────────────────┤
│       1 │                0 │ -z, x, -y            │          1 │ [ 0. -1.  0.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │          1 │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
├─────────┼──────────────────┼──────────────────────┼────────────┼──────────────────┼─────────────────────┼─────────┼────────────┼─────────┼────────────┼────────────┼─────────────────────┼─────────────────────────────────────────────────────┤
│       2 │                0 │ y, -z, -x            │          1 │ [-0. -0.  1.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │          1 │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
╘═════════╧══════════════════╧══════════════════════╧════════════╧══════════════════╧═════════════════════╧═════════╧════════════╧═════════╧════════════╧════════════╧═════════════════════╧═════════════════════════════════════════════════════╛

Onsite (Inter-Orbital) Couplings:
╒═════════╤══════════════════╤══════════════════════╤════════════╤══════════════════╤═════════════════════╤═════════╤════════════╤═════════╤════════════╤════════════╤═════════════════════╤══════════╕
│ index   │ symmetry index   │ symmetry operation   │ distance   │ lattice_vector   │ sublattice_vector   │ site1   │ orbital1   │ site2   │ orbital2   │ strength   │ spin-orbit vector   │ matrix   │
╞═════════╪══════════════════╪══════════════════════╪════════════╪══════════════════╪═════════════════════╪═════════╪════════════╪═════════╪════════════╪════════════╪═════════════════════╪══════════╡
╘═════════╧══════════════════╧══════════════════════╧════════════╧══════════════════╧═════════════════════╧═════════╧════════════╧═════════╧════════════╧════════════╧═════════════════════╧══════════╛
set_label(index: int, label: str) None[source]

Sets a custom label to a given site.

This is just for custom labels and has no effect on any calculation.

Parameters:
  • index (int) – The index of the site.

  • label (str) – The label.

Examples

We assign the label ‘A’ to the site.

In [1]: model.set_label(0, 'A')

In [2]: model.show_site_properties()
╒═════════╤═══════════╤═════════╤════════════╤═══════════════════════╤═══════════════════════╤══════════╤═════════════════╤═════════════════╤═════════════════════════════════════════════════════╤═══════════════════╤════════════════════╤═════════╕
│   index │ species   │ label   │   orbitals │ coordinates (latt.)   │ coordinates (cart.)   │ magmom   │   onsite scalar │ onsite vector   │ onsite matrix                                       │ unit cell index   │ supercell vector   │ layer   │
╞═════════╪═══════════╪═════════╪════════════╪═══════════════════════╪═══════════════════════╪══════════╪═════════════════╪═════════════════╪═════════════════════════════════════════════════════╪═══════════════════╪════════════════════╪═════════╡
│       0 │ Co1       │ A       │          1 │ [0. 0. 0.]            │ [0. 0. 0.]            │          │               0 │ [0. 0. 0.]      │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │         │
╘═════════╧═══════════╧═════════╧════════════╧═══════════════════════╧═══════════════════════╧══════════╧═════════════════╧═════════════════╧═════════════════════════════════════════════════════╧═══════════════════╧════════════════════╧═════════╛
Spin Polarized: False
Zeeman: [0. 0. 0.]
Supercell Size: None
set_moments(orientations: VectorList, magnitudes: RealList = None) None[source]

Sets the magnetic moments on each site of the structure given in lattice coordinates.

Parameters:
  • orientations (VectorList) – A list of three-dimensional vectors that specify the direction of local magnetic moment on each site.

  • magnitudes (RealList) – A list of floats that specifies the magnitude of the local moment for each site. If None, the length of the input vector is used. Default is None.

Examples

Put spin-1/2 moments on the site that point into the 111-direction.

In [1]: model.set_moments([[1, 1, 1]], [0.5])

In [2]: model.show_site_properties()
╒═════════╤═══════════╤═════════╤════════════╤═══════════════════════╤═══════════════════════╤════════════════════════════════════╤═════════════════╤═════════════════╤═════════════════════════════════════════════════════╤═══════════════════╤════════════════════╤═════════╕
│   index │ species   │ label   │   orbitals │ coordinates (latt.)   │ coordinates (cart.)   │ magmom                             │   onsite scalar │ onsite vector   │ onsite matrix                                       │ unit cell index   │ supercell vector   │ layer   │
╞═════════╪═══════════╪═════════╪════════════╪═══════════════════════╪═══════════════════════╪════════════════════════════════════╪═════════════════╪═════════════════╪═════════════════════════════════════════════════════╪═══════════════════╪════════════════════╪═════════╡
│       0 │ Co1       │ A       │          1 │ [0. 0. 0.]            │ [0. 0. 0.]            │ [0.28867513 0.28867513 0.28867513] │               0 │ [0. 0. 0.]      │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │         │
╘═════════╧═══════════╧═════════╧════════════╧═══════════════════════╧═══════════════════════╧════════════════════════════════════╧═════════════════╧═════════════════╧═════════════════════════════════════════════════════╧═══════════════════╧════════════════════╧═════════╛
Spin Polarized: False
Zeeman: [0. 0. 0.]
Supercell Size: None
set_onsite_matrix(index: int, matrix: float | SquareMatrix, overwrite: bool = True) None[source]

Sets a onsite matrix to a given site.

TODO: implement this for the pseudo diplor terms and single-ion anisotropies For a TightBindingModel this is nothing? For SpinWaveModel this term is a onsite spin interaction matrix.

Parameters:
  • index (int) – The index of the site.

  • matrix (SquareMatrix) – The matrix of the onsite term.

  • overwrite (bool) – If true, any existing term is overwritten. If false, the term is added. Default is true.

Examples

We assign a easy-axis blabla…

#model.set_onsite_scalar(0, 0.25)
#model.show_site_properties()
set_onsite_scalar(index: int, strengths: float | RealList, space_group: int = 1, overwrite: bool = True) None[source]

Sets a scalar onsite energy to a given site.

For a TightBindingModel this is a site or orbital dependent onsite energy. For SpinWaveModel this term is ignored.

Parameters:
  • index (int) – The index of the site.

  • strengths (float | RealList) – The strength of the onsite term. If there are multiple orbitals on the site, a list must be passed.

  • space_group (int) – If a compatible space group symmetry is selected, the term will automatically be assigned to all symmetrically equivalent sites. Default is None.

  • overwrite (bool) – If true, any existing term is overwritten. If false, the term is added. Default is true.

Examples

We assign a onsite energy of E = 0.25 to the zeroth site. See the onsite scalar column in the output.

In [1]: model.set_onsite_scalar(0, 0.25)

In [2]: model.show_site_properties()
╒═════════╤═══════════╤═════════╤════════════╤═══════════════════════╤═══════════════════════╤════════════════════════════════════╤═════════════════╤═════════════════╤═════════════════════════════════════════════════════╤═══════════════════╤════════════════════╤═════════╕
│   index │ species   │ label   │   orbitals │ coordinates (latt.)   │ coordinates (cart.)   │ magmom                             │   onsite scalar │ onsite vector   │ onsite matrix                                       │ unit cell index   │ supercell vector   │ layer   │
╞═════════╪═══════════╪═════════╪════════════╪═══════════════════════╪═══════════════════════╪════════════════════════════════════╪═════════════════╪═════════════════╪═════════════════════════════════════════════════════╪═══════════════════╪════════════════════╪═════════╡
│       0 │ Co1       │ A       │          1 │ [0. 0. 0.]            │ [0. 0. 0.]            │ [0.28867513 0.28867513 0.28867513] │            0.25 │ [0. 0. 0.]      │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │         │
╘═════════╧═══════════╧═════════╧════════════╧═══════════════════════╧═══════════════════════╧════════════════════════════════════╧═════════════════╧═════════════════╧═════════════════════════════════════════════════════╧═══════════════════╧════════════════════╧═════════╛
Spin Polarized: False
Zeeman: [0. 0. 0.]
Supercell Size: None
set_onsite_vector(index: int, vector: Vector, strength: float = None, space_group: int = 1, overwrite: bool = True) None[source]

Sets an onsite vector to a given site.

NOTE: Implement this for multi-orbital! For a SpinWaveModel this corresponds to a single-ion anisotropy. For a TightBindingModel to a local magnetic field.

Parameters:
  • index (int) – The index of the site.

  • vector (Vector) – The orientation of the term.

  • strength (float) – The strength of the onsite term. If None, the length of the input vector is used. Default is None.

  • space_group (int) – If a compatible space group symmetry is selected, the term will automatically be assigned to all symmetrically equivalent sites and the assigned vector will be rotated accordingly. Default is None.

  • overwrite (bool) – If true, any existing term is overwritten. If false, the term is added. Default is true.

Notes

If the model is a topwave.model.TightBindingModel calling this method will make the model spinful. The dimension of the Hilbert space will be doubled. See topwave.model.TightBindingModel.check_if_spinful.

Examples

We assign a single-ion anisotropy of strength A = 0.1 along the 111-direction. See the onsite vector column in the output.

In [1]: model.set_onsite_vector(0, [1, 1, 1], 0.1)

In [2]: model.show_site_properties()
╒═════════╤═══════════╤═════════╤════════════╤═══════════════════════╤═══════════════════════╤════════════════════════════════════╤═════════════════╤════════════════════════════════════╤═════════════════════════════════════════════════════╤═══════════════════╤════════════════════╤═════════╕
│   index │ species   │ label   │   orbitals │ coordinates (latt.)   │ coordinates (cart.)   │ magmom                             │   onsite scalar │ onsite vector                      │ onsite matrix                                       │ unit cell index   │ supercell vector   │ layer   │
╞═════════╪═══════════╪═════════╪════════════╪═══════════════════════╪═══════════════════════╪════════════════════════════════════╪═════════════════╪════════════════════════════════════╪═════════════════════════════════════════════════════╪═══════════════════╪════════════════════╪═════════╡
│       0 │ Co1       │ A       │          1 │ [0. 0. 0.]            │ [0. 0. 0.]            │ [0.28867513 0.28867513 0.28867513] │            0.25 │ [0.05773503 0.05773503 0.05773503] │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │         │
╘═════════╧═══════════╧═════════╧════════════╧═══════════════════════╧═══════════════════════╧════════════════════════════════════╧═════════════════╧════════════════════════════════════╧═════════════════════════════════════════════════════╧═══════════════════╧════════════════════╧═════════╛
Spin Polarized: False
Zeeman: [0. 0. 0.]
Supercell Size: None
set_open_boundaries(direction: str = 'xyz') None[source]

Sets the exchange/hopping and DM/SOC at the chosen boundary to zero.

Parameters:

direction (str) – The directions in lattice vectors along which the boundary conditions are set to open. ‘x’ is along the direction of the first lattice vector. ‘yz’ along the other two, and ‘xyz/ in all directions.

Examples

Set open boundaries in y- and z-direction so that we have a one-dimensional chain along x. See the strength column in the output.

In [1]: model.set_open_boundaries('yz')

In [2]: model.show_couplings()
╒═════════╤══════════════════╤══════════════════════╤════════════╤══════════════════╤═════════════════════╤═════════╤════════════╤═════════╤════════════╤════════════╤═════════════════════╤═════════════════════════════════════════════════════╕
│   index │   symmetry index │ symmetry operation   │   distance │ lattice_vector   │ sublattice_vector   │   site1 │   orbital1 │   site2 │   orbital2 │   strength │ spin-orbit vector   │ matrix                                              │
╞═════════╪══════════════════╪══════════════════════╪════════════╪══════════════════╪═════════════════════╪═════════╪════════════╪═════════╪════════════╪════════════╪═════════════════════╪═════════════════════════════════════════════════════╡
│       0 │                0 │ x, y, z              │          1 │ [ 1. -0. -0.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │          1 │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
├─────────┼──────────────────┼──────────────────────┼────────────┼──────────────────┼─────────────────────┼─────────┼────────────┼─────────┼────────────┼────────────┼─────────────────────┼─────────────────────────────────────────────────────┤
│       1 │                0 │ -z, x, -y            │          1 │ [ 0. -1.  0.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │          0 │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
├─────────┼──────────────────┼──────────────────────┼────────────┼──────────────────┼─────────────────────┼─────────┼────────────┼─────────┼────────────┼────────────┼─────────────────────┼─────────────────────────────────────────────────────┤
│       2 │                0 │ y, -z, -x            │          1 │ [-0. -0.  1.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │          0 │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
╘═════════╧══════════════════╧══════════════════════╧════════════╧══════════════════╧═════════════════════╧═════════╧════════════╧═════════╧════════════╧════════════╧═════════════════════╧═════════════════════════════════════════════════════╛

Onsite (Inter-Orbital) Couplings:
╒═════════╤══════════════════╤══════════════════════╤════════════╤══════════════════╤═════════════════════╤═════════╤════════════╤═════════╤════════════╤════════════╤═════════════════════╤══════════╕
│ index   │ symmetry index   │ symmetry operation   │ distance   │ lattice_vector   │ sublattice_vector   │ site1   │ orbital1   │ site2   │ orbital2   │ strength   │ spin-orbit vector   │ matrix   │
╞═════════╪══════════════════╪══════════════════════╪════════════╪══════════════════╪═════════════════════╪═════════╪════════════╪═════════╪════════════╪════════════╪═════════════════════╪══════════╡
╘═════════╧══════════════════╧══════════════════════╧════════════╧══════════════════╧═════════════════════╧═════════╧════════════╧═════════╧════════════╧════════════╧═════════════════════╧══════════╛
set_spin_orbit(attribute_value: int | float, vector: Vector, strength: float = None, attribute: str = 'index') None[source]

Assigns spin dependent hopping/antisymmetric exchange to a selection of couplings.

If the couplings are grouped by symmetry, the assigned exchanges will be rotated automatically according to space group symmetry.

Parameters:
  • attribute_value (int | float) – The value of the selected attribute.

  • vector (Vector) – Orientation of the term.

  • strength (float) – Strength of the term. If None, the length of the orientation is used. Default is None.

  • attribute (str) –

    The attribute by which the couplings are selected. Options are ‘is_set’, ‘index’,

    ’symmetry_id’, ‘distance’ or ‘lattice_vector’.

Examples

Assign antisymmetric exchange with finite z-component along nearest neighbor in the x-direction. See the ‘spin-orbit vector’ column in the output.

In [1]: model.set_spin_orbit(0, [0, 0, 0.05])

In [2]: model.show_couplings()
╒═════════╤══════════════════╤══════════════════════╤════════════╤══════════════════╤═════════════════════╤═════════╤════════════╤═════════╤════════════╤════════════╤═════════════════════╤═════════════════════════════════════════════════════╕
│   index │   symmetry index │ symmetry operation   │   distance │ lattice_vector   │ sublattice_vector   │   site1 │   orbital1 │   site2 │   orbital2 │   strength │ spin-orbit vector   │ matrix                                              │
╞═════════╪══════════════════╪══════════════════════╪════════════╪══════════════════╪═════════════════════╪═════════╪════════════╪═════════╪════════════╪════════════╪═════════════════════╪═════════════════════════════════════════════════════╡
│       0 │                0 │ x, y, z              │          1 │ [ 1. -0. -0.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │          1 │ [0.   0.   0.05]    │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
├─────────┼──────────────────┼──────────────────────┼────────────┼──────────────────┼─────────────────────┼─────────┼────────────┼─────────┼────────────┼────────────┼─────────────────────┼─────────────────────────────────────────────────────┤
│       1 │                0 │ -z, x, -y            │          1 │ [ 0. -1.  0.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │          0 │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
├─────────┼──────────────────┼──────────────────────┼────────────┼──────────────────┼─────────────────────┼─────────┼────────────┼─────────┼────────────┼────────────┼─────────────────────┼─────────────────────────────────────────────────────┤
│       2 │                0 │ y, -z, -x            │          1 │ [-0. -0.  1.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │          0 │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
╘═════════╧══════════════════╧══════════════════════╧════════════╧══════════════════╧═════════════════════╧═════════╧════════════╧═════════╧════════════╧════════════╧═════════════════════╧═════════════════════════════════════════════════════╛

Onsite (Inter-Orbital) Couplings:
╒═════════╤══════════════════╤══════════════════════╤════════════╤══════════════════╤═════════════════════╤═════════╤════════════╤═════════╤════════════╤════════════╤═════════════════════╤══════════╕
│ index   │ symmetry index   │ symmetry operation   │ distance   │ lattice_vector   │ sublattice_vector   │ site1   │ orbital1   │ site2   │ orbital2   │ strength   │ spin-orbit vector   │ matrix   │
╞═════════╪══════════════════╪══════════════════════╪════════════╪══════════════════╪═════════════════════╪═════════╪════════════╪═════════╪════════════╪════════════╪═════════════════════╪══════════╡
╘═════════╧══════════════════╧══════════════════════╧════════════╧══════════════════╧═════════════════════╧═════════╧════════════╧═════════╧════════════╧════════════╧═════════════════════╧══════════╛
set_spin_polarized()[source]

Spin polarizes the system.

For a tight-binding model, only terms from the spin-up sector will be considered when constructing the Hamiltonian. For a spinwave model, only the upper right hand block matrix that corresponds to the BdG block of positive momentum will be considered.

Tip

If only terms that do not couple to the spin, e.g. scalar hoppings or onsite terms, are given, the model is also spinless.

Examples

Spin polarize the system and confirm by printing the site properties.

In [1]: model.set_spin_polarized()

In [2]: model.show_site_properties()
╒═════════╤═══════════╤═════════╤════════════╤═══════════════════════╤═══════════════════════╤════════════════════════════════════╤═════════════════╤════════════════════════════════════╤═════════════════════════════════════════════════════╤═══════════════════╤════════════════════╤═════════╕
│   index │ species   │ label   │   orbitals │ coordinates (latt.)   │ coordinates (cart.)   │ magmom                             │   onsite scalar │ onsite vector                      │ onsite matrix                                       │ unit cell index   │ supercell vector   │ layer   │
╞═════════╪═══════════╪═════════╪════════════╪═══════════════════════╪═══════════════════════╪════════════════════════════════════╪═════════════════╪════════════════════════════════════╪═════════════════════════════════════════════════════╪═══════════════════╪════════════════════╪═════════╡
│       0 │ Co1       │ A       │          1 │ [0. 0. 0.]            │ [0. 0. 0.]            │ [0.28867513 0.28867513 0.28867513] │            0.25 │ [0.05773503 0.05773503 0.05773503] │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │         │
╘═════════╧═══════════╧═════════╧════════════╧═══════════════════════╧═══════════════════════╧════════════════════════════════════╧═════════════════╧════════════════════════════════════╧═════════════════════════════════════════════════════╧═══════════════════╧════════════════════╧═════════╛
Spin Polarized: True
Zeeman: [0. 0. 0.]
Supercell Size: None
set_zeeman(orientation: Vector, strength: float = None) None[source]

Sets a global Zeeman term.

Tip

For ferromagnetic systems a small Zeeman term is recommended to lift the soft mode above zero energy.

Parameters:
  • orientation (Vector) – The orientation of the Zeeman term.

  • strength (float) – The strength of the Zeeman term in units of Tesla. If None, the length of the orientation is used. Default is None.

Notes

If the model is a topwave.model.TightBindingModel calling this method will make the model spinful. The dimension of the Hilbert space will be doubled. See topwave.model.TightBindingModel.check_if_spinful.

Examples

We set a Zeeman field of 0.2 Tesla in the 111-direction.

In [1]: model.set_zeeman([1, 1, 1], 0.2)

In [2]: model.show_site_properties()
╒═════════╤═══════════╤═════════╤════════════╤═══════════════════════╤═══════════════════════╤════════════════════════════════════╤═════════════════╤════════════════════════════════════╤═════════════════════════════════════════════════════╤═══════════════════╤════════════════════╤═════════╕
│   index │ species   │ label   │   orbitals │ coordinates (latt.)   │ coordinates (cart.)   │ magmom                             │   onsite scalar │ onsite vector                      │ onsite matrix                                       │ unit cell index   │ supercell vector   │ layer   │
╞═════════╪═══════════╪═════════╪════════════╪═══════════════════════╪═══════════════════════╪════════════════════════════════════╪═════════════════╪════════════════════════════════════╪═════════════════════════════════════════════════════╪═══════════════════╪════════════════════╪═════════╡
│       0 │ Co1       │ A       │          1 │ [0. 0. 0.]            │ [0. 0. 0.]            │ [0.28867513 0.28867513 0.28867513] │            0.25 │ [0.05773503 0.05773503 0.05773503] │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │         │
╘═════════╧═══════════╧═════════╧════════════╧═══════════════════════╧═══════════════════════╧════════════════════════════════════╧═════════════════╧════════════════════════════════════╧═════════════════════════════════════════════════════╧═══════════════════╧════════════════════╧═════════╛
Spin Polarized: True
Zeeman: [0.11547005 0.11547005 0.11547005]
Supercell Size: None
show_couplings() None[source]

Prints the couplings.

show_site_properties() None[source]

Prints the site properties.

unset_coupling(attribute_value: int | float, attribute: str = 'index') None[source]

Removes exchanges from a coupling and makes it unset.

Parameters:
  • attribute (str) –

    The attribute by which the couplings are selected. Options are ‘is_set’, ‘index’,

    ’symmetry_id’, ‘distance’ or ‘lattice_vector’.

  • value (int | float) – The value of the selected attribute.

Examples

We unset the coupling along the x-direction.

In [1]: print(model.couplings[0].is_set)
True

In [2]: model.unset_coupling(0)

In [3]: model.couplings[0].is_set
Out[3]: False
unset_moments()[source]

Unsets all magnetic moments of the structure.

Examples

We set the magnetic moment on all sites to zero.

In [1]: model.unset_moments()

In [2]: model.show_site_properties()
╒═════════╤═══════════╤═════════╤════════════╤═══════════════════════╤═══════════════════════╤══════════╤═════════════════╤════════════════════════════════════╤═════════════════════════════════════════════════════╤═══════════════════╤════════════════════╤═════════╕
│   index │ species   │ label   │   orbitals │ coordinates (latt.)   │ coordinates (cart.)   │ magmom   │   onsite scalar │ onsite vector                      │ onsite matrix                                       │ unit cell index   │ supercell vector   │ layer   │
╞═════════╪═══════════╪═════════╪════════════╪═══════════════════════╪═══════════════════════╪══════════╪═════════════════╪════════════════════════════════════╪═════════════════════════════════════════════════════╪═══════════════════╪════════════════════╪═════════╡
│       0 │ Co1       │ A       │          1 │ [0. 0. 0.]            │ [0. 0. 0.]            │          │            0.25 │ [0.05773503 0.05773503 0.05773503] │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │         │
╘═════════╧═══════════╧═════════╧════════════╧═══════════════════════╧═══════════════════════╧══════════╧═════════════════╧════════════════════════════════════╧═════════════════════════════════════════════════════╧═══════════════════╧════════════════════╧═════════╛
Spin Polarized: True
Zeeman: [0.11547005 0.11547005 0.11547005]
Supercell Size: None
unset_spin_polarized()[source]

Sets the spin-polarization flag to False.

Examples

Unset spin-polarization and confirm by printing the site properties.

In [1]: model.unset_spin_polarized()

In [2]: model.show_site_properties()
╒═════════╤═══════════╤═════════╤════════════╤═══════════════════════╤═══════════════════════╤══════════╤═════════════════╤════════════════════════════════════╤═════════════════════════════════════════════════════╤═══════════════════╤════════════════════╤═════════╕
│   index │ species   │ label   │   orbitals │ coordinates (latt.)   │ coordinates (cart.)   │ magmom   │   onsite scalar │ onsite vector                      │ onsite matrix                                       │ unit cell index   │ supercell vector   │ layer   │
╞═════════╪═══════════╪═════════╪════════════╪═══════════════════════╪═══════════════════════╪══════════╪═════════════════╪════════════════════════════════════╪═════════════════════════════════════════════════════╪═══════════════════╪════════════════════╪═════════╡
│       0 │ Co1       │ A       │          1 │ [0. 0. 0.]            │ [0. 0. 0.]            │          │            0.25 │ [0.05773503 0.05773503 0.05773503] │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │         │
╘═════════╧═══════════╧═════════╧════════════╧═══════════════════════╧═══════════════════════╧══════════╧═════════════════╧════════════════════════════════════╧═════════════════════════════════════════════════════╧═══════════════════╧════════════════════╧═════════╛
Spin Polarized: False
Zeeman: [0.11547005 0.11547005 0.11547005]
Supercell Size: None
write_cif(path: str, write_magmoms: bool = True) None[source]

Saves the structure to a .mcif file.

Parameters:
  • path (str) – Where to save the structure.

  • write_magmoms (bool) – If true the magnetic moments are written into the mcif file. Default is True.

class topwave.model.SpinWaveModel(structure: Structure, import_site_properties: bool = False)[source]

Class for Linear Spinwave models.

Examples

Create a ferromagnetic chain of cobalt atoms.

# Create a three-dimensional cubic structure.
In [1]: from pymatgen.core.structure import Structure

In [2]: structure = Structure.from_spacegroup(sg=1, lattice=np.eye(3), species=['Co'], coords=[[0, 0, 0]])

# Create a SpinWaveModel.
In [3]: model = tp.model.SpinWaveModel(structure)

# Put a ferromagnetic configuration of local moments.
In [4]: model.set_moments([[0, 0, 1]])

# Couple the local moments ferromagnetically along the x-direction.
In [5]: model.generate_couplings(1, 1)

In [6]: model.set_coupling(0, strength=-1)

# Put local mom
In [7]: model.show_couplings()
╒═════════╤══════════════════╤══════════════════════╤════════════╤══════════════════╤═════════════════════╤═════════╤════════════╤═════════╤════════════╤════════════╤═════════════════════╤═════════════════════════════════════════════════════╕
│   index │   symmetry index │ symmetry operation   │   distance │ lattice_vector   │ sublattice_vector   │   site1 │   orbital1 │   site2 │   orbital2 │ strength   │ spin-orbit vector   │ matrix                                              │
╞═════════╪══════════════════╪══════════════════════╪════════════╪══════════════════╪═════════════════════╪═════════╪════════════╪═════════╪════════════╪════════════╪═════════════════════╪═════════════════════════════════════════════════════╡
│       0 │                0 │ x, y, z              │          1 │ [-1.  0.  0.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │ -1         │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
├─────────┼──────────────────┼──────────────────────┼────────────┼──────────────────┼─────────────────────┼─────────┼────────────┼─────────┼────────────┼────────────┼─────────────────────┼─────────────────────────────────────────────────────┤
│       1 │                1 │ x, y, z              │          1 │ [ 0. -1.  0.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │ 0j         │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
├─────────┼──────────────────┼──────────────────────┼────────────┼──────────────────┼─────────────────────┼─────────┼────────────┼─────────┼────────────┼────────────┼─────────────────────┼─────────────────────────────────────────────────────┤
│       2 │                2 │ x, y, z              │          1 │ [ 0.  0. -1.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │ 0j         │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
╘═════════╧══════════════════╧══════════════════════╧════════════╧══════════════════╧═════════════════════╧═════════╧════════════╧═════════╧════════════╧════════════╧═════════════════════╧═════════════════════════════════════════════════════╛

Onsite (Inter-Orbital) Couplings:
╒═════════╤══════════════════╤══════════════════════╤════════════╤══════════════════╤═════════════════════╤═════════╤════════════╤═════════╤════════════╤════════════╤═════════════════════╤══════════╕
│ index   │ symmetry index   │ symmetry operation   │ distance   │ lattice_vector   │ sublattice_vector   │ site1   │ orbital1   │ site2   │ orbital2   │ strength   │ spin-orbit vector   │ matrix   │
╞═════════╪══════════════════╪══════════════════════╪════════════╪══════════════════╪═════════════════════╪═════════╪════════════╪═════════╪════════════╪════════════╪═════════════════════╪══════════╡
╘═════════╧══════════════════╧══════════════════════╧════════════╧══════════════════╧═════════════════════╧═════════╧════════════╧═════════╧════════════╧════════════╧═════════════════════╧══════════╛

In [8]: model.show_site_properties()
╒═════════╤═══════════╤═════════╤════════════╤═══════════════════════╤═══════════════════════╤════════════╤═════════════════╤═════════════════╤═════════════════════════════════════════════════════╤═══════════════════╤════════════════════╤═════════╕
│   index │ species   │ label   │   orbitals │ coordinates (latt.)   │ coordinates (cart.)   │ magmom     │   onsite scalar │ onsite vector   │ onsite matrix                                       │ unit cell index   │ supercell vector   │ layer   │
╞═════════╪═══════════╪═════════╪════════════╪═══════════════════════╪═══════════════════════╪════════════╪═════════════════╪═════════════════╪═════════════════════════════════════════════════════╪═══════════════════╪════════════════════╪═════════╡
│       0 │ Co1       │         │          1 │ [0. 0. 0.]            │ [0. 0. 0.]            │ [0. 0. 1.] │               0 │ [0. 0. 0.]      │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │         │
╘═════════╧═══════════╧═════════╧════════════╧═══════════════════════╧═══════════════════════╧════════════╧═════════════════╧═════════════════╧═════════════════════════════════════════════════════╧═══════════════════╧════════════════════╧═════════╛
Spin Polarized: False
Zeeman: [0. 0. 0.]
Supercell Size: None

See also

topwave.model.Model, IntroductionToSpinWaveModel

get_classical_energy(per_spin: bool = True) float[source]

Computes the classical ground state energy of the model with its current orientation of local moments.

Parameters:

per_spin (bool) – If true, the energy is divided by the number of local moments in the model. Default is True.

Returns:

The classical energy.

Return type:

float

Examples

Compute the classical energy of the ferromagnetic Heisenberg chain with J=-1 meV.

In [1]: model.get_classical_energy()
Out[1]: (-1+0j)
get_classical_groundstate(random_init=False) None[source]

Minimize the classical energy by changing the orientation of the magnetic moments.

This method can be used to find the classical groundstate configuration of a model. The magnitude of the local moments is fixed, and only their orientation is adjusted. Scipy’s minimize function is used.

Frustration and (In)Commensurability

If the classical ground state is frustrated, there might not be a unique configuration that minimizes the classical energy. Consider putting an external magnetic field or single-ion anisotropies in that case. If the system is incommensurable consider minimizing the energy of a supercell and play around with open and periodic boundary conditions.

Todo

Add example and references to supercell and set_open_boundaries.

Parameters:

random_init (bool) – If True, the orientation of magnetic moments is randomly initialized. The moments need to be set before regardless to extract their magnitudes. If false the set orientations are used. Default is False.

get_type() str[source]

Returns the type of the Model.

Returns:

Returns ‘spinwave’.

Return type:

str

class topwave.model.TightBindingModel(structure: Structure, import_site_properties: bool = False)[source]

Class for Tight Binding models.

Examples

Create a tightbinding model of graphene.

In [1]: from pymatgen.core.structure import Lattice, Structure

In [2]: lattice = Lattice.hexagonal(1.42, 10)

In [3]: structure = Structure.from_spacegroup(sg=191, lattice=lattice, species=['C'], coords=[[1 / 3, 2 / 3, 0]])

In [4]: print(structure)
Full Formula (C2)
Reduced Formula: C
abc   :   1.420000   1.420000  10.000000
angles:  90.000000  90.000000 120.000000
pbc   :       True       True       True
Sites (2)
  #  SP           a         b    c
---  ----  --------  --------  ---
  0  C     0.333333  0.666667    0
  1  C     0.666667  0.333333    0

In [5]: graphene = tp.model.TightBindingModel(structure)

See also

topwave.model.Model, IntroductionToTightBindingModel

check_if_spinful() bool[source]

Checks whether the model is spinful or spinless (polarized).

This method checks whether there are any terms set that are spin dependent. This includes Zeeman terms, spin-orbit coupling, or local magnetic field (onsite vector terms).

Returns:

True if the system is spinful, False if not.

Return type:

bool

Notes

If the model is a topwave.model.TightBindingModel calling this method will make the model spinful. The dimension of the Hilbert space will be doubled. See topwave.model.TightBindingModel.check_if_spinful.

Examples

In [1]: graphene.check_if_spinful()
Out[1]: False
get_type() str[source]

Overrides the ‘get_type’-method to return the tightbinding type.

set_orbitals(index: int, num_orbitals: int) None[source]

Sets the number of orbitals on a given site.

Coming soon!

Still in Development. So far this only sets the number of orbitals as a site property, but it doesn’t influence the spectrum.

k_space_utils

topwave.k_space_utils.get_line_cover(normal: str, direction: str, num_lines: int, num_points: int, anchor: float = 0.0, min: float = - 0.5, max: float = 0.5) list[VectorList][source]

Builds a rectangular cover of a plane through the Brillouin zone.

Parameters:
  • normal (str) – A string indicating the normal of the plane in units of reciprocal lattice vectors. Options are ‘x’, ‘y’ or ‘z’.

  • direction (str) – In which direction the lines are stacked. Options are ‘x’ and ‘y’.

  • num_lines (int) – Number of lines that are used to span the plane.

  • num_points (int) – Number of points on one line.

  • anchor (float) – Where along the normal the plane is anchored. Default is 0.

  • min (float) – At which coordinate along the direction the first line is anchored.

  • max (float) – At which coordinate along the direction the last line is anchored.

Returns:

A num_lines-long list of lines that each contains num_points k-points. The first and last k-point are connected by a reciprocal lattice vector.

Return type:

list[VectorList]

Examples

We create a cover of the xy-plane anchored at z = 0 with 30 lines stacked along the x-direction. Each line consists fo 60 points.

In [1]: import numpy as np

In [2]: import matplotlib.pyplot as plt

# Create the cover.
In [3]: cover = tp.get_line_cover('z', 'x', 30, 60)

In [4]: fig = plt.figure()

In [5]: ax = plt.axes(projection='3d')

In [6]: for line in cover:
   ...:     ax.plot(*line.T, c='hotpink')
   ...: 

In [7]: ax.set_xlim(-0.5, 0.5)
Out[7]: (-0.5, 0.5)

In [8]: ax.set_ylim(-0.5, 0.5)
Out[8]: (-0.5, 0.5)

In [9]: ax.set_zlim(-0.5, 0.5)
Out[9]: (-0.5, 0.5)

In [10]: ax.set_xlabel(r'$k_x$');

In [11]: ax.set_ylabel(r'$k_y$');

In [12]: ax.set_zlabel(r'$k_z$');
savefig/line_cover.png
topwave.k_space_utils.get_plaquette_cover(normal: str, num_x: int, num_y: int, anchor: float = 0.0, x_min: float = - 0.5, x_max: float = 0.5, y_min: float = - 0.5, y_max: float = 0.5, closed: bool = True) list[VectorList][source]

Builds a rectangular cover of a plane through the Brillouin zone.

Parameters:
  • normal (str) – A string indicating the normal of the plane in units of reciprocal lattice vectors. Options are ‘x’, ‘y’ or ‘z’.

  • num_x (int) – Number of plaquettes along the first vector that spans the plane.

  • num_y (int) – Number of plaquettes along the second vector that spans the plane.

  • anchor (float) – Where along the normal the plane is anchored. Default is 0.

  • x_min (float) – First component of the first point of the cover.

  • x_max (float) – First component of the end point of the cover.

  • y_min (float) – Second component of the first point of the cover.

  • y_max (float) – Second component of the end point of the cover.

  • closed (bool) – If True, the first and last k-point of the plaquette are identified with each other by adding a fifth point, e.g. for the calculation of Wilson loops. Default is True.

Returns:

A list of sets of four reciprocal vectors that correspond to the corner points of the plaquettes.

Return type:

list[VectorList]

Notes

If the cover is used to compute topological invariants, e.g. the Berry curvature, make sure that the cover spans the whole Brillouin zone exactly once. In other words, do not touch x_min, x_max, y_min and y_max.

Examples

We create a 10-by-10 cover of the xy-plane anchored at z = 0.

In [1]: import numpy as np

In [2]: from matplotlib.patches import Polygon

In [3]: from matplotlib.collections import PatchCollection

In [4]: import matplotlib.pyplot as plt

# Create the cover.
In [5]: cover = tp.get_plaquette_cover('z', 10, 10, closed=False)

# We plot each plaquette as a polygon and give it a random color.
In [6]: np.random.seed(188)

In [7]: fig, ax = plt.subplots()

In [8]: patches = []

In [9]: for plaquette in cover:
   ...:     patches.append(Polygon(plaquette[:, :2], closed=True))
   ...: 

In [10]: colors = 100 * np.random.rand(len(patches))

In [11]: p = PatchCollection(patches, cmap=plt.cm.hsv)

In [12]: p.set_array(colors)

In [13]: ax.add_collection(p)
Out[13]: <matplotlib.collections.PatchCollection at 0x7fb181ee3a50>

In [14]: ax.set_xlim(-0.5, 0.5)
Out[14]: (-0.5, 0.5)

In [15]: ax.set_ylim(-0.5, 0.5)
Out[15]: (-0.5, 0.5)

In [16]: ax.set_aspect('equal')
savefig/plaquette_cover.png

response

class topwave.response.Susceptibility(model: TightBindingModel, num_matsubara_frequencies: int, k_grid_shape: tuple[int, int, int], temperature: float)[source]

Class for calculations of charge and spin susceptibilities and doing random phase approximation.

Examples

Do random phase approximation on a square lattice.

In [1]: print('Coming soon!')
Coming soon!
bare_susceptibility: ndarray[float64]
contract(operator_left: SquareMatrix = None, operator_right: SquareMatrix = None, intracell_phase_factors: bool = True) ndarray[float64][source]

Contracts the susceptibility rank four tensor with operators.

Parameters:
  • operator_left (SquareMatrix) – The left operator. If None, the identity matrix is used. Default is None.

  • operator_right (SquareMatrix) – The right operator. If None, the identity matrix is used. Default is None.

  • intracell_phase_factors (bool) – If True, the intracell phase factors are accounted for. Default is True.

Returns:

The bare susceptibility contracted to a rank two tensor (at each frequency and k-points).

Return type:

np.ndarray[np.float64]

static get_bare_susceptibility(model: TightBindingModel, grid: Grid, num_matsubara_frequencies: int, temperature: float) ndarray[float64][source]

Computes the bare susceptibility tensor for a given model.

This uses the imaginary time representation to efficiently calculate the product of Green’s functions. Cite Something

Parameters:
  • model (TightBindingModel) – A list of tight-binding hamiltonians on a grid that covers the Brillouin zone that is used to calculate the bare suscpetibility. The shape should be the shape of the grid times the dimension of the hamiltonians.

  • grid (Grid) – A grid of k-points on which the susceptibility is computed.

  • num_matsubara_frequencies (int) – The number of matsubara frequencies. Increase this number until convergence is reached. A good starting point is 256.

  • temperature (float) – The temperature in the units of the hopping amplitudes. 2 percent of the largest hopping amplitude is a good starting value.

Returns:

The bare susceptibility. The shape is the shape of the kpoint-grid times for indices that run over the number of bands.

Return type:

np.ndarray[np.float64]

Notes

Make sure that the grid that covers the BZ does not include the endpoints so that there is no double counting. And that the hamiltonian is reshaped properly. See also…

Examples

We calculate the bare susceptibilty of the square lattice and a single orbital.

# create a two-dimensional square lattice
In [1]: from pymatgen.core.structure import Structure

In [2]: a, vacuum = 1, 10

In [3]: lattice = [[a, 0, 0], [0, a, 0], [0, 0, vacuum]]

In [4]: struc = Structure.from_spacegroup(1, lattice, ['Cu'], [np.zeros(3)])

# Construct a Model instance and set nearest neighbor couplings
In [5]: model = tp.TightBindingModel(struc)

In [6]: model.generate_couplings(1, 1)

In [7]: t1 = -1

In [8]: model.set_coupling(a, t1, "distance")

In [9]: model.show_couplings()
╒═════════╤══════════════════╤══════════════════════╤════════════╤══════════════════╤═════════════════════╤═════════╤════════════╤═════════╤════════════╤════════════╤═════════════════════╤═════════════════════════════════════════════════════╕
│   index │   symmetry index │ symmetry operation   │   distance │ lattice_vector   │ sublattice_vector   │   site1 │   orbital1 │   site2 │   orbital2 │   strength │ spin-orbit vector   │ matrix                                              │
╞═════════╪══════════════════╪══════════════════════╪════════════╪══════════════════╪═════════════════════╪═════════╪════════════╪═════════╪════════════╪════════════╪═════════════════════╪═════════════════════════════════════════════════════╡
│       0 │                0 │ x, y, z              │          1 │ [-1.  0.  0.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │         -1 │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
├─────────┼──────────────────┼──────────────────────┼────────────┼──────────────────┼─────────────────────┼─────────┼────────────┼─────────┼────────────┼────────────┼─────────────────────┼─────────────────────────────────────────────────────┤
│       1 │                1 │ x, y, z              │          1 │ [ 0. -1.  0.]    │ [0. 0. 0.]          │       0 │          0 │       0 │          0 │         -1 │ [0. 0. 0.]          │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │
╘═════════╧══════════════════╧══════════════════════╧════════════╧══════════════════╧═════════════════════╧═════════╧════════════╧═════════╧════════════╧════════════╧═════════════════════╧═════════════════════════════════════════════════════╛

Onsite (Inter-Orbital) Couplings:
╒═════════╤══════════════════╤══════════════════════╤════════════╤══════════════════╤═════════════════════╤═════════╤════════════╤═════════╤════════════╤════════════╤═════════════════════╤══════════╕
│ index   │ symmetry index   │ symmetry operation   │ distance   │ lattice_vector   │ sublattice_vector   │ site1   │ orbital1   │ site2   │ orbital2   │ strength   │ spin-orbit vector   │ matrix   │
╞═════════╪══════════════════╪══════════════════════╪════════════╪══════════════════╪═════════════════════╪═════════╪════════════╪═════════╪════════════╪════════════╪═════════════════════╪══════════╡
╘═════════╧══════════════════╧══════════════════════╧════════════╧══════════════════╧═════════════════════╧═════════╧════════════╧═════════╧════════════╧════════════╧═════════════════════╧══════════╛
grid: Grid
k_grid_shape: tuple[int, int, int]
model: TightBindingModel
num_matsubara_frequencies: int
temperature: float
topwave.response.get_nernst_conductivity(berry_curvature: ListOfRealList, energies: ListOfRealList, filling: float, temperature: float) float[source]

Computes the Nernst Conductivity.

Parameters:
  • berry_curvature (ListOfRealList) – The Berry Curvature at each k-point for all bands.

  • energies (ListOfRealList) – The energies at each k-point for all bands.

  • filling (float) – The energy up to which the states are considered.

  • temperature (float) – The temperature.

Returns:

The Nernst conductivity at some filling.

Return type:

float

set_of_kpoints

class topwave.set_of_kpoints.Circle(radius: float, center: Vector, normal: Vector, num_kpoints: int = 100, endpoint: bool = True)[source]

A circle through reciprocal space.

Parameters:
  • radius (float) – Radius in reduced reciprocal lattice units of the circle.

  • center (Vector) – Where in reciprocal space the circle is centered.

  • normal (Vector) – The normal of the plane the circle lies in.

  • num_kpoints (int) – The number of k-points used to parameterize the circle. Default is 100.

  • endpoint (bool) – If True, the first and last point are identified, e.g. for Wilson loop calculations. Default is True.

kpoints

List of points in reciprocal space in reduced coordinates.

Type:

VectorList

normal

This is where normal is saved.

Type:

Vector

num_kpoints

Number of k-points.

Type:

int

Examples

Let’s create a path from Gamma to M to K and back to Gamma.

In [1]: circle = tp.Circle(radius=0.2, center=[0, 0, 0], normal=[1, 0, 1])

In [2]: fig = plt.figure()

In [3]: ax = plt.axes(projection='3d')

In [4]: ax.scatter(*circle.kpoints.T)
Out[4]: <mpl_toolkits.mplot3d.art3d.Path3DCollection at 0x7fb17fd2ed50>

In [5]: ax.set_xlabel(r'$k_x$')
Out[5]: Text(0.5, 0, '$k_x$')

In [6]: ax.set_ylabel(r'$k_y$')
Out[6]: Text(0.5, 0.5, '$k_y$')

In [7]: ax.set_zlabel(r'$k_z$')
Out[7]: Text(0.5, 0, '$k_z$')
savefig/circle.png
class topwave.set_of_kpoints.Grid(num_x: int, num_y: int, num_z: int, x_min: float = - 0.5, x_max: float = 0.5, y_min: float = - 0.5, y_max: float = 0.5, z_min: float = - 0.5, z_max: float = 0.5, endpoint_x: bool = False, endpoint_y: bool = False, endpoint_z: bool = False)[source]

A grid through the Brillouin zone.

Parameters:
  • num_x (int) – Number of points along the first vector that spans the grid.

  • num_y (int) – Number of points along the second vector that spans the grid.

  • num_z (int) – Number of points along the third vector that spans the grid.

  • x_min (float) – First component of the first point of the grid. Default is -0.5.

  • x_max (float) – First component of the end point of the grid. Default is 0.5.

  • y_min (float) – Second component of the first point of the grid. Default is -0.5.

  • y_max (float) – Second component of the end point of the grid. Default is 0.5.

  • z_min (float) – Third component of the first point of the grid. Default is -0.5.

  • z_max (float) – Third component of the end point of the grid. Default is 0.5.

  • endpoint_x (bool) – If True, x_max is the boundary of the plane in the first direction. Default is False.

  • endpoint_y (bool) – If True, y_max is the boundary of the plane in the first direction. Default is False.

  • endpoint_z (bool) – If True, z_max is the boundary of the plane in the first direction. Default is False.

extent

This is where x_min, x_max, y_min, y_max, z_min, z_max are stored.

Type:

tuple[float, float, float, float, float, float]

kpoints

List of points in reciprocal space in reduced coordinates.

Type:

VectorList

num_kpoints

Number of k-points.

Type:

int

shape

This is where num_x, num_y and num_z are saved.

Type:

tuple(int, int)

Notes

If the plane is used to compute quantities that are obtained by integrating over the Brillouin zone in three-dimensions, e.g. the bare susceptibility, set endpoint_x, endpoint_y and endpoint_z to False to avoid double counting the points on the boundaries of the plane and make sure that x_min, x_max, y_min, y_max, z_min and z_max span the full Brillouin zone.

Examples

We construct two grids and plot them.

In [1]: import matplotlib.pyplot as plt

# Create the grids.
In [2]: num_x, num_y, num_z = 15, 15, 15

In [3]: grid1 = tp.Grid(num_x, num_y, num_z)

In [4]: grid2 = tp.Grid(num_x, num_y, num_z, x_min=0.75, x_max=1.25, y_min=0.75, y_max=1.25, z_min=0.75, z_max=1.25)

In [5]: fig = plt.figure()

In [6]: ax = plt.axes(projection='3d')

In [7]: ax.scatter(*grid1.kpoints.T)
Out[7]: <mpl_toolkits.mplot3d.art3d.Path3DCollection at 0x7fb181eb1890>

In [8]: ax.scatter(*grid2.kpoints.T)
Out[8]: <mpl_toolkits.mplot3d.art3d.Path3DCollection at 0x7fb1822bae10>

In [9]: ax.set_xlabel(r'$k_x$');

In [10]: ax.set_ylabel(r'$k_y$');

In [11]: ax.set_zlabel(r'$k_z$');
savefig/grid.png
class topwave.set_of_kpoints.Path(nodes: VectorList, segment_lengths: list[int] = None)[source]

Path through reciprocal space.

Parameters:
  • nodes (VectorList) – List of (high-symmetry) points between which a path is created.

  • segment_lengths (IntVector) – Number of points for each segment along the path. If None, its 100 points per segment. Default is None.

kpoints

List of points in reciprocal space in reduced coordinates.

Type:

VectorList

nodes

This is where nodes is saved.

Type:

VectorList

node_indices

Indices of the kpoints that correspond to the nodes.

Type:

IntVector

num_kpoints

Number of kpoints.

Type:

int

segment_lenghts

Number of kpoints between each node.

Type:

IntVector

Examples

Let’s create a path from Gamma to M to K and back to Gamma.

In [1]: path = tp.Path([[0, 0, 0],
   ...:                 [1 / 2, 0, 0],
   ...:                 [1 / 3, 1 / 3, 0],
   ...:                 [0, 0, 0]])
   ...: 

In [2]: fig, ax = plt.subplots()

In [3]: ax.plot(*path.kpoints[:, :2].T)
Out[3]: [<matplotlib.lines.Line2D at 0x7fb18239ad50>]

In [4]: ax.scatter(*path.nodes[:, :2].T)
Out[4]: <matplotlib.collections.PathCollection at 0x7fb18239b110>

In [5]: ax.set_xlabel(r'$k_x$')
Out[5]: Text(0.5, 0, '$k_x$')

In [6]: ax.set_ylabel(r'$k_y$')
Out[6]: Text(0, 0.5, '$k_y$')
savefig/path.png
class topwave.set_of_kpoints.Plane(normal: Vector, num_x: int, num_y: int, anchor: float = 0.0, x_min: float = - 0.5, x_max: float = 0.5, y_min: float = - 0.5, y_max: float = 0.5, endpoint_x: bool = False, endpoint_y: bool = False)[source]

A plane through the Brillouin zone.

Parameters:
  • normal (Vector) – The normal of the plane.

  • num_x (int) – Number of points along the first vector that spans the plane.

  • num_y (int) – Number of points along the second vector that spans the plane.

  • anchor (float) – Where along the normal the plane is anchored. Default is 0

  • x_min (float) – First component of the first point of the plane. Default is -0.5.

  • x_max (float) – First component of the end point of the plane. Default is 0.5.

  • y_min (float) – Second component of the first point of the plane. Default is -0.5.

  • y_max (float) – Second component of the end point of the plane. Default is 0.5.

  • endpoint_x (bool) – If True, x_max is the boundary of the plane in the first direction. Default is False.

  • endpoint_y (bool) – If True, y_max is the boundary of the plane in the first direction. Default is False.

anchor

This is where anchor is saved.

Type:

float

extent

This is where x_min, x_max, y_min and y_max are stored.

Type:

tuple[float, float, float, float]

kpoints

List of points in reciprocal space in reduced coordinates.

Type:

VectorList

normal

This is where normal is saved.

Type:

Vector

num_kpoints

Number of k-points.

Type:

int

shape

This is where num_x and num_y are saved.

Type:

tuple(int, int)

Notes

If the plane is used to compute quantities that are obtained by integrating over the Brillouin zone in two-dimensions, e.g. the density of states of graphene, set endpoint_x and endpoint_y to False to avoid double counting the points on the boundaries of the plane and leave make sure x_min, x_max, y_min and y_max span the full Brillouin zone.

Examples

We construct three planes and plot them.

In [1]: import matplotlib.pyplot as plt

# Create the planes.
In [2]: num_x, num_y = 31, 31

In [3]: plane_xy = tp.Plane([0, 0, 1], num_x, num_y, endpoint_x=True, endpoint_y=True)

In [4]: plane_xy_shifted = tp.Plane([0, 0, 1], num_x, num_y, anchor=0.1, endpoint_x=True, endpoint_y=True)

In [5]: plane_101 = tp.Plane([1, 0, 1], num_x, num_y, endpoint_x=True, endpoint_y=True)

In [6]: fig = plt.figure()

In [7]: ax = plt.axes(projection='3d')

In [8]: for plane in [plane_xy, plane_xy_shifted, plane_101]:
   ...:     ax.scatter(*plane.kpoints.T)
   ...: 

In [9]: ax.set_xlabel(r'$k_x$');

In [10]: ax.set_ylabel(r'$k_y$');

In [11]: ax.set_zlabel(r'$k_z$');
savefig/plane.png
class topwave.set_of_kpoints.SetOfKPoints(kpoints: VectorList)[source]

Class that holds a number of k-points in three dimensional reciprocal space.

Parameters:

kpoints (VectorList) – List of points in reciprocal space in reduced coordinates.

kpoints

This is where kpoints is stored.

Type:

VectorList

num_kpoints

Number of kpoints.

Type:

int

class topwave.set_of_kpoints.Sphere(radius: float, center: Vector, num_phi: int, num_theta: int, endpoint_phi: bool = False, startpoint_theta: bool = False, endpoint_theta: bool = False, d_cos_theta: bool = False)[source]

A Sphere in the Brillouin zone.

Parameters:
  • radius (float) – The radius of the sphere in reduced reciprocal coordinates.

  • center (Vector) – The center of the sphere in reduced reciprocal coordinates.

  • num_phi (int) – Number of points along lines on the sphere with constant elevation.

  • num_theta (int) – Number of points along lines on the sphere with constant azimuthal angle.

  • endpoint_phi (bool) – Whether or not the 2pi is included in lines of constant elevation. Default is False.

  • startpoint_theta (bool) – Whether or not 0 is included in the lines of constant azimuthal angle. Default is False.

  • endpoint_theta (bool) – Whether or not pi is included in the lines of constant azimuthal angle. Default is False.

  • d_cos_theta (bool) – If False, the increment of elevation angle is equidistant in angle. If True, the increment of elevation angle is equidistant in the cosine of angle. Default is False.

center

This is where center is stored.

Type:

Vector

kpoints

List of points in reciprocal space in reduced coordinates.

Type:

VectorList

num_kpoints

Number of k-points.

Type:

int

radius

This is where redius is stored.

Type:

float

shape

This is where num_phi and num_theta are saved.

Type:

tuple(int, int)

Notes

If the sphere is used to compute the chirality of e.g. a Weyl point make sure to exclude 0 and pi elevation angle and to close the lines of constant elevation. If you chose d_cos_theta to be False, the points close to the poles of the sphere are much closer together than at the equator.

Examples

We construct two spheres with the two different increments of elevation angle.

In [1]: import matplotlib.pyplot as plt

# Create the grids.
In [2]: num_phi, num_theta = 15, 10

In [3]: sphere1 = tp.Sphere(radius=0.3, center=[-0.2, -0.2, 0], num_phi=num_phi, num_theta=num_theta, d_cos_theta=True)

In [4]: sphere2 = tp.Sphere(radius=0.25, center=[0.25, 0.25, 0.25], num_phi=num_phi, num_theta=num_theta)

In [5]: fig = plt.figure()

In [6]: ax = plt.axes(projection='3d')

In [7]: ax.scatter(*sphere1.kpoints.T)
Out[7]: <mpl_toolkits.mplot3d.art3d.Path3DCollection at 0x7fb1823c08d0>

In [8]: ax.scatter(*sphere2.kpoints.T)
Out[8]: <mpl_toolkits.mplot3d.art3d.Path3DCollection at 0x7fb1824ec310>

In [9]: ax.set_xlim(-0.5, 0.5)
Out[9]: (-0.5, 0.5)

In [10]: ax.set_ylim(-0.5, 0.5)
Out[10]: (-0.5, 0.5)

In [11]: ax.set_zlim(-0.5, 0.5)
Out[11]: (-0.5, 0.5)

In [12]: ax.set_xlabel(r'$k_x$');

In [13]: ax.set_ylabel(r'$k_y$');

In [14]: ax.set_zlabel(r'$k_z$');
savefig/sphere.png

solvers

topwave.solvers.colpa(H: SquareMatrix) tuple[RealList, SquareMatrix][source]

Diagonalizes a bosonic Hamiltonian.

Caution!

This routine relies on the Hamiltonian to be positive (semi)definite. If the magnetic configuration in the model does not minimize the classical energy (e.g. in frustrated systems) that is not the case.

Parameters:

H (SquareMatrix) – Bosonic positive (semi)definite Hamiltonian.

Returns:

Eigenvalues w and Eigenvectors v. The column v[:, i] corresponds to the eigenvalue w[i].

Return type:

tuple[RealList, SquareMatrix]

References

The function uses the algorithm presented in https://doi.org/10.1016/0378-4371(86)90056-7.

spec

class topwave.spec.Spec(model: Model, kpoints: numpy.ndarray[numpy.float64] | list[numpy.ndarray[numpy.float64]] | list[list[float]] | topwave.set_of_kpoints.SetOfKPoints)[source]

Computes the spectrum of a model for a given set of k-points.

energies: ndarray[Any, dtype[float64]]
get_berry_phase(band_indices: numpy.ndarray[numpy.int64] | list[int] = None, energy: float = None, nonabelian: bool = False) float[source]

Computes the Berry phase.

get_density_of_states(energies: numpy.ndarray[numpy.float64] | list[float], broadening: float = 0.02) numpy.ndarray[numpy.float64] | list[float][source]

Computes the density of states:

Parameters:
  • energies (RealList) – Energies at which the density of states is calculated.

  • broadening (float) – Broadening of the spectral density. Default is 0.02.

Returns:

The density of states.

Return type:

RealList

Examples

Calculate some DOS.

get_inverse_band_distance(band_index1: int, band_index2: int, broadening: float = 0.02) numpy.ndarray[numpy.float64] | list[float][source]

Computes a measure of how degenerate two bands are at each k-point.

Parameters:
  • band_index1 (int) – Index of the first band.

  • band_index2 (int) – Index of the second band.

  • broadening (float) – Broadening. Default is 0.02.

Returns:

The inverted band distance at each k-point of the spectrum.

Return type:

RealList

Examples

Compute the inverted band distance of something.

get_particle_density(filling: float) ndarray[source]

Computes the electron density for all occupied states.

Parameters:

filling (float) – The energy up to which states are considered.

Returns:

Array with the electron densities. The shape is (num_unit_cell_x, num_unit_cell_y, num_unit_cell_z, num_sublattices, num_spins)

Return type:

np.ndarray

get_spectral_density(energy: float = 0.0, broadening: float = 0.02) numpy.ndarray[numpy.float64] | list[float][source]

Computes the spectral density at a given energy for all k-points of the spectrum:

Parameters:
  • energy (float) – The energy at which the spectral density is computed.

  • broadening (float) – Broadening of the spectral density. Default is 0.02.

Returns:

The spectral density at each k-point of the spectrum.

Return type:

RealList

Examples

Compute the spectral density of something.

static get_spinwave_derivative(model: SpinWaveModel, kpoints: numpy.ndarray[numpy.float64] | list[numpy.ndarray[numpy.float64]] | list[list[float]] | topwave.set_of_kpoints.SetOfKPoints, derivative: str) ndarray[Any, dtype[complex128]][source]

Constructs the spin wave Hamiltonian for a set of given k-points.

static get_spinwave_hamiltonian(model: SpinWaveModel, kpoints: numpy.ndarray[numpy.float64] | list[numpy.ndarray[numpy.float64]] | list[list[float]] | topwave.set_of_kpoints.SetOfKPoints) ndarray[Any, dtype[complex128]][source]

Constructs the spin wave Hamiltonian for a set of given k-points.

static get_tightbinding_derivative(model: TightBindingModel, kpoints: numpy.ndarray[numpy.float64] | list[numpy.ndarray[numpy.float64]] | list[list[float]] | topwave.set_of_kpoints.SetOfKPoints, derivative: str) ndarray[complex128][source]

Constructs the derivative of a Tight Binding Hamiltonian for a given set of k-points.

TODO: update for multi-orbital :param model: The model of that is used to calculate the spectrum. :type model: TightBindingModel :param kpoints: The kpoints at which the Hamiltonian or its derivatives are constructed. :type kpoints: VectorList | SetOfKPoints :param derivative: String that indicates which derivative should be constructed. Options are ‘x’, ‘y’ or ‘z’. :type derivative: str

Returns:

The derivative of the Hamiltonian.

Return type:

SquareMatrix

static get_tightbinding_hamiltonian(model: TightBindingModel, kpoints: numpy.ndarray[numpy.float64] | list[numpy.ndarray[numpy.float64]] | list[list[float]] | topwave.set_of_kpoints.SetOfKPoints) ndarray[complex128][source]

Constructs the Tight Binding Hamiltonian for a given set of k-points.

Parameters:
  • model (TightBindingModel) – The model of that is used to calculate the spectrum.

  • kpoints (VectorList | SetOfKPoints) – The kpoints at which the Hamiltonian or its derivatives are constructed.

Returns:

The Hamiltonian.

Return type:

SquareMatrix

hamiltonian: ndarray[Any, dtype[float64]]
kpoints: numpy.ndarray[numpy.float64] | list[numpy.ndarray[numpy.float64]] | list[list[float]] | topwave.set_of_kpoints.SetOfKPoints
model: Model
psi: ndarray[Any, dtype[float64]]
solve(solver: Callable[[ndarray[Any, dtype[complex128]]], tuple[numpy.ndarray[Any, numpy.dtype[numpy.complex128]], numpy.ndarray[Any, numpy.dtype[numpy.complex128]]]]) tuple[numpy.ndarray[Any, numpy.dtype[numpy.complex128]], numpy.ndarray[Any, numpy.dtype[numpy.complex128]]][source]

Diagonalizes the Hamiltonian using the provided solver.

supercell

topwave.supercell.get_supercell(model: Model, scaling_factors: numpy.ndarray[numpy.float64] | list[float]) Model[source]

Creates a supercell of a given model.

topwave.supercell.stack(layers: list[topwave.model.Model], spacings: numpy.ndarray[numpy.float64] | list[float], direction: str = 'z', vacuum: float = 10) Model[source]

Creates stacks of models in a given stacking direction.

This function creates stacked models. Onsite properties and intralayer couplings are transferred to the new model. Because the resulting model is usually treated as two-dimensional, the method adds vacuum to the new unit cell.

Compatible Lattices

This method assumes that the models have the same lattice structure, i.e. the unit cell area within the plane is not increased by the stacking.

Parameters:
  • layers (list[Model]) – A list of models that are stacked on top of each other.

  • spacings (RealList) – List of floats that specify the interlayer distances in Angstrom. Length should be the number of models minus 1.

  • direction (str) – A string indicating along which lattice vector the models are stacked. Options are ‘x’, ‘y’ and ‘z’. Default is ‘z’.

  • vacuum (float) – How much vacuum in Angstrom is added to the stacked unit cell. Default is 10.

Returns:

The stacked model.

Return type:

Model

Examples

Create an bernal bilayer of graphene.

# build two graphene models with staggered displacement fields (onsite terms)
In [1]: lattice = Lattice.hexagonal(1.42, 1)

In [2]: layer_A = Structure.from_spacegroup(sg=191, lattice=lattice, species=['C'], coords=[[1 / 3, 2 / 3, 0]])

In [3]: layer_B = layer_A.copy()

# shift layer_B to get bernal-type stacking
In [4]: layer_B.translate_sites(indices=[0, 1], vector=layer_A.frac_coords[0])
Out[4]: 
Structure Summary
Lattice
    abc : 1.42 1.42 1.0
 angles : 90.0 90.0 119.99999999999999
 volume : 1.7462536241909419
      A : 1.42 0.0 8.694992273946207e-17
      B : -0.7099999999999999 1.2297560733739028 8.694992273946207e-17
      C : 0.0 0.0 1.0
    pbc : True True True
PeriodicSite: C (0.71, 0.4099, 8.695e-17) [0.6667, 0.3333, 0.0]
PeriodicSite: C (0.0, 0.0, 0.0) [0.0, 0.0, 0.0]

In [5]: model_A, model_B = tp.TightBindingModel(layer_A), tp.TightBindingModel(layer_B)

In [6]: displacement_field = 0.2

In [7]: model_A.set_onsite_scalar(1, displacement_field)

In [8]: model_B.set_onsite_scalar(0, -displacement_field)

# stack the models with interlayer distance 3.44 Angstrom
In [9]: model_bernal = tp.stack([model_A, model_B], [3.44])

# the onsite terms have been transferred (see column 'onsite scalar')
In [10]: model_bernal.show_site_properties()
╒═════════╤═══════════╤═════════╤════════════╤═══════════════════════════════════════════════════╤═══════════════════════════════════════════════════╤══════════╤═════════════════╤═════════════════╤═════════════════════════════════════════════════════╤═══════════════════╤════════════════════╤═════════╕
│   index │ species   │ label   │   orbitals │ coordinates (latt.)                               │ coordinates (cart.)                               │ magmom   │   onsite scalar │ onsite vector   │ onsite matrix                                       │ unit cell index   │ supercell vector   │   layer │
╞═════════╪═══════════╪═════════╪════════════╪═══════════════════════════════════════════════════╪═══════════════════════════════════════════════════╪══════════╪═════════════════╪═════════════════╪═════════════════════════════════════════════════════╪═══════════════════╪════════════════════╪═════════╡
│       0 │ C1        │         │          1 │ [ 3.33333333e-01  6.66666667e-01 -9.41449788e-35] │ [-7.09999093e-11  8.19837382e-01  8.69499227e-17] │          │             0   │ [0. 0. 0.]      │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │       0 │
├─────────┼───────────┼─────────┼────────────┼───────────────────────────────────────────────────┼───────────────────────────────────────────────────┼──────────┼─────────────────┼─────────────────┼─────────────────────────────────────────────────────┼───────────────────┼────────────────────┼─────────┤
│       1 │ C1        │         │          1 │ [ 6.66666667e-01  3.33333333e-01 -9.41449788e-35] │ [7.10000000e-01 4.09918691e-01 8.69499227e-17]    │          │             0.2 │ [0. 0. 0.]      │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │       0 │
├─────────┼───────────┼─────────┼────────────┼───────────────────────────────────────────────────┼───────────────────────────────────────────────────┼──────────┼─────────────────┼─────────────────┼─────────────────────────────────────────────────────┼───────────────────┼────────────────────┼─────────┤
│       2 │ C1        │         │          1 │ [0.66666667 0.33333333 0.25595238]                │ [0.71       0.40991869 3.44      ]                │          │            -0.2 │ [0. 0. 0.]      │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │       1 │
├─────────┼───────────┼─────────┼────────────┼───────────────────────────────────────────────────┼───────────────────────────────────────────────────┼──────────┼─────────────────┼─────────────────┼─────────────────────────────────────────────────────┼───────────────────┼────────────────────┼─────────┤
│       3 │ C1        │         │          1 │ [0.         0.         0.25595238]                │ [0.   0.   3.44]                                  │          │             0   │ [0. 0. 0.]      │ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] │                   │                    │       1 │
╘═════════╧═══════════╧═════════╧════════════╧═══════════════════════════════════════════════════╧═══════════════════════════════════════════════════╧══════════╧═════════════════╧═════════════════╧═════════════════════════════════════════════════════╧═══════════════════╧════════════════════╧═════════╛
Spin Polarized: False
Zeeman: [0. 0. 0.]
Supercell Size: None

# plot the supercell when supercell is updated

topology

topwave.topology.get_berry_curvature(spec: Spec, component: str) list[RealList][source]

Computes the Berry curvature using

\[\Omega_k = - \sum_{n ≠ m} \frac{\langle \psi_n \partial_\mu \hat{H} \psi_m \rangle}{(\epsilon_n - \epsilon_m)^2}\]

This is so far only for the fermionic berry curvature.

Examples

we compute

topwave.topology.get_berry_phase(loop_operator: Matrix) float[source]

Computes the Berry phase of a Wilson loop:

\[\phi = - \sum \operatorname{Im} \ln \det M^{(\Lambda_{i}, \Lambda_{i+1})},\]

with

\[M^{(\Lambda_{i}, \Lambda_{i+1})}_{mn} = \langle u_m^{(\Lambda_{i})} u_n^{(\Lambda_{i+1})}\]

angle

Compute the Berry phase of something.

topwave.topology.get_bosonic_berry_curvature(spec: Spec, component: str) list[RealList][source]

Computes the bosonic Berry curvature.

Note make a switch for bosonic vs fermionic in ONE function.

Examples

we compute

topwave.topology.get_bosonic_wilson_loop(spectrum: Spec, band_indices: IntVector) Matrix[source]

Constructs the Wilson loop operator of a bosonic spectrum.

topwave.topology.get_fermionic_wilson_loop(spectrum: Spec, band_indices: IntVector = None, energy: float = None) Matrix[source]

Constructs the Wilson loop operator of a fermionic spectrum.

For a spectrum at Nk k-points, the inner product of Nk - 1 eigenfunctions for a given selection of states is evaluated. The ordering is the same as that of the k-points. The states can be selected by providing a list of band indices, or all states below some energy can be selected. In that case the wilson loop operator is a product of rectangular matrices.

Careful!

Typically, closed Wilson loops of the occupied states are the desired quantities. Make sure the last and first k-point of the spectrum are the same, and all selected bands are separated in energy (nondegenerate).

Parameters:
  • spectrum (Spec) – The spectrum that contains the eigenfunctions of the model.

  • band_indices (IntVector) – List of band indices that are selected to compute the Wilson loop operator. If None, all states are selected.

  • energy (float) – If not None, only states below energy are used to compute the Wilson loop. Default is None.

topwave.topology.get_nonabelian_berry_phase(loop_operator: Matrix) float[source]

Computes the Berry phase of a Wilson loop:

\[\phi = - \sum \operatorname{Im} \ln \det M^{(\Lambda_{i}, \Lambda_{i+1})},\]

with

\[M^{(\Lambda_{i}, \Lambda_{i+1})}_{mn} = \langle u_m^{(\Lambda_{i})} u_n^{(\Lambda_{i+1})}\]

angle

Compute the Berry phase of something.

util

topwave.util.bose_distribution(energies: Union[float, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]], temperature: float) ndarray[Any, dtype[float64]][source]

Calculates the Bose-Einstein distribution for a given set of energies and a temperature.

topwave.util.coupling_selector(attribute: str, value: int | float, couplings: list[Coupling]) list[int][source]

Selects couplings based on a given attribute.

topwave.util.fermi_distribution(energies: Union[float, _SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]], temperature: float) ndarray[Any, dtype[float64]][source]

Calculates the Fermi-Dirac distribution for a given set of energies and a temperature.

topwave.util.format_input_vector(orientation: list[float] | numpy.ndarray[Any, numpy.dtype[numpy.float64]], length: Optional[float] = None) ndarray[Any, dtype[float64]][source]

Normalizes an input vector and scales it by length, or does nothing if length=None.

topwave.util.format_kpoints(kpoints: VectorList | SetOfKPoints) VectorList[source]

Makes sure that either a list of k-points or a SetOfKPoints instance can be used.

topwave.util.gaussian(x: int | float | numpy.ndarray[Any, numpy.dtype[numpy.float64]], mean: float, std: float, normalize: bool = True) ndarray[Any, dtype[float64]][source]

Evaluates the normal distribution at x.

topwave.util.get_angle(vector1: Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]], vector2: Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]], deg: bool = False) float[source]

Returns the angle of two vectors.

topwave.util.get_azimuthal_angle(vector: Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]], deg: bool = False) float[source]

Returns the azimuthal angle of a three component vector w.r.t. [1, 0, 0].

topwave.util.get_berry_curvature_indices(component: str) tuple[int, int][source]

Returns the indices of the crystal momenta needed to calculate the given component of the Berry Curvature.

topwave.util.get_boundary_couplings(model: Model, direction: str = 'xyz') npt.NDArray[np.int64][source]

Returns indices of couplings that change the unit cell in a given direction.

topwave.util.get_elevation_angle(vector: Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]], deg: bool = False) float[source]

Returns the elevation angle of a three component vector w.r.t. [0, 0, 1].

topwave.util.get_plaquette_indices(normal: str) tuple[int, int, int][source]
topwave.util.get_span_indices(normal: str) tuple[int, int, int][source]
topwave.util.pauli(vector: Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]], normalize: bool = True) ndarray[Any, dtype[complex128]][source]

Outputs a linear combination of Pauli matrices given by the input vector.

topwave.util.rotate_vector(vector: Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]], angle: float, axis: Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]], basis: Optional[Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]] = None) ndarray[Any, dtype[float64]][source]

Rotates a 3 component vector by a given angle (in radians) about an arbitrary axis.

topwave.util.rotate_vector_to_ez(vector: Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]) ndarray[Any, dtype[float64]][source]

Creates a 3x3 rotation matrix R with R v = [0, 0, 1].

topwave.util.site_selector(attribute: str, value: int | str | float, model: Model) list[int][source]

Selects sites based on a given attribute.