pyextal.superspace.modulation

Modulation functions and the modulated atom.

In a modulated structure an atom’s position, occupancy and displacement parameters are not numbers but functions of the internal coordinate xbar = (xbar_4, ..., xbar_(3+d)), periodic with period 1 in each component. Everything here is a truncated Fourier series in that coordinate:

u(xbar) = sum_n [ A_n sin(2 pi n.xbar) + B_n cos(2 pi n.xbar) ]

with n a d-dimensional integer harmonic index. The published 1T-TaS2 refinement used 21 harmonics on Ta and 12 on S, so the representation has to carry an arbitrary number of them rather than assume a single wave.

Displacements are held in fractional coordinates of the basic cell, which makes the structure-factor phase a plain dot product with the effective reciprocal index and keeps the units straight.

Classes

Harmonic

One term of a Fourier series in the internal coordinate.

DisplaciveModulation

Positional modulation: a displacement field over internal space.

OccupationalModulation

Occupancy as a function of internal coordinate.

ModulatedAtom

One atom of the basic structure, with its modulation functions.

Functions

phase_shift(series, tau)

The same modulation seen from an internal-space origin moved by tau.

invert(series)

The modulation of the atom related to this one by a centre of symmetry.

Module Contents

class pyextal.superspace.modulation.Harmonic

One term of a Fourier series in the internal coordinate.

Variables:
  • n (tuple) – (d,) integer harmonic index.

  • sin (np.ndarray) – Amplitude of the sine term – (3,) for a displacive modulation, () for an occupational one.

  • cos (np.ndarray) – Amplitude of the cosine term, same shape as sin.

n: tuple
sin: numpy.ndarray
cos: numpy.ndarray
__post_init__()
property order

sum |n_j|, the harmonic order.

Type:

int

class pyextal.superspace.modulation.DisplaciveModulation(harmonics=(), d=1)

Bases: _FourierSeries

Positional modulation: a displacement field over internal space.

Variables:
  • harmonics (tuple[Harmonic]) – Terms with (3,) amplitudes, in fractional coordinates of the basic cell.

  • d (int) – Number of modulation dimensions.

evaluate(xbar)

Displacement at each internal coordinate.

Parameters:

xbar (np.ndarray) – (npts, d) internal coordinates.

Returns:

(npts, 3) displacement in fractional coordinates; all zeros when there are no harmonics.

Return type:

np.ndarray

max_amplitude()

float: Largest single-harmonic amplitude, for grid sizing.

class pyextal.superspace.modulation.OccupationalModulation(average=1.0, harmonics=(), d=1)

Bases: _FourierSeries

Occupancy as a function of internal coordinate.

Variables:
  • average (float) – The n = 0 term, i.e. the mean occupancy.

  • harmonics (tuple[Harmonic]) – Terms with scalar amplitudes.

  • d (int) – Number of modulation dimensions.

average
evaluate(xbar)

Occupancy at each internal coordinate.

Parameters:

xbar (np.ndarray) – (npts, d) internal coordinates.

Returns:

(npts,) occupancies.

Return type:

np.ndarray

class pyextal.superspace.modulation.ModulatedAtom

One atom of the basic structure, with its modulation functions.

Variables:
  • label (str) – Free-form name, e.g. 'Ta1'.

  • element (str) – Symbol used to look up the scattering factor.

  • position (np.ndarray) – (3,) fractional coordinates in the basic cell.

  • occupancy (float) – Site occupancy of the basic structure; ignored when occupational is set, which carries its own average.

  • B (float) – Isotropic displacement parameter in Angstrom^2. Modulated ADPs are not implemented – see the module note in structurefactor.

  • displacive (DisplaciveModulation, optional) – Positional modulation.

  • occupational (OccupationalModulation, optional) – Occupancy modulation.

label: str
element: str
position: numpy.ndarray
occupancy: float = 1.0
B: float = 0.0
displacive: DisplaciveModulation = None
occupational: OccupationalModulation = None
__post_init__()
displacement(xbar)

Displacement field, zeros if the atom is not positionally modulated.

Parameters:

xbar (np.ndarray) – (npts, d) internal coordinates.

Returns:

(npts, 3) fractional displacements.

Return type:

np.ndarray

occupation(xbar)

Occupancy field, constant if the atom is not occupationally modulated.

Parameters:

xbar (np.ndarray) – (npts, d) internal coordinates.

Returns:

(npts,) occupancies.

Return type:

np.ndarray

pyextal.superspace.modulation.phase_shift(series, tau)

The same modulation seen from an internal-space origin moved by tau.

An atom generated by a superspace centring translation (E | t, tau_i) carries its parent’s modulation evaluated at xbar - tau_i. Rewriting

A sin(2 pi n.(xbar - tau)) + B cos(2 pi n.(xbar - tau))

back into sine and cosine of 2 pi n.xbar mixes the two amplitudes through phi = 2 pi n.tau:

A' =  A cos(phi) + B sin(phi)
B' = -A sin(phi) + B cos(phi)

which is exact, so no resampling or interpolation is involved.

Parameters:
Returns:

The same type as series with shifted harmonics, or None if series was None.

pyextal.superspace.modulation.invert(series)

The modulation of the atom related to this one by a centre of symmetry.

Inversion sends r -> -r, hence xbar -> -xbar and u -> -u, so u'(xbar) = -u(-xbar): the sine amplitudes are unchanged and the cosine amplitudes change sign. An atom sitting on an inversion centre must therefore have no cosine terms at all – which is exactly why the published 1T-TaS2 refinement reports every cosine amplitude of Ta as zero.

Parameters:

series (DisplaciveModulation) – The parent’s modulation, or None.

Returns:

The image atom’s modulation.

Return type:

DisplaciveModulation or None