pyextal.superspace.symmetry¶
Superspace symmetry operations.
A (3+d) superspace operation is a 3D operation (R | tau) together with its
action (epsilon | tau_i) on the internal coordinates. The internal part is
not free: it is determined by R through how R rearranges the modulation
wave vectors,
R^T q_j = sum_k epsilon_jk q_k + G_j, G_j a reciprocal lattice vector,
and epsilon_for() solves that for epsilon and G. Getting this
wrong is a quiet failure – the structure factors come out plausible and the
symmetry-equivalent reflections simply do not match.
Scope¶
transform_reflection() is general: the G_j terms fold cleanly into the
main indices. expand_atoms() is not – it is implemented only for
operations with every G_j = 0, because a nonzero G_j makes the phase
relation between symmetry-equivalent modulation functions depend on the atom’s
own position, which needs the full superspace-group machinery to get right. It
raises rather than guessing. For a structure where that bites, list the atoms in
P1; that is what tas2 does.
Classes¶
One symmetry operation of a (3+d) superspace group. |
Functions¶
|
Solve |
|
Apply a superspace operation to reflection indices. |
|
Generate the symmetry-equivalent atoms and their modulation functions. |
Module Contents¶
- class pyextal.superspace.symmetry.SuperspaceOperation¶
One symmetry operation of a (3+d) superspace group.
- Variables:
R (np.ndarray) – (3, 3) integer rotation on direct fractional coordinates.
tau (np.ndarray) – (3,) translation part, fractional.
epsilon (np.ndarray) – (d, d) integer action on internal coordinates.
tau_i (np.ndarray) – (d,) internal translation.
G (np.ndarray) – (d, 3) integer reciprocal lattice vectors from the q-transformation; all zero for the well-behaved settings.
name (str) – Optional label.
- R: numpy.ndarray¶
- tau: numpy.ndarray = None¶
- epsilon: numpy.ndarray = None¶
- tau_i: numpy.ndarray = None¶
- G: numpy.ndarray = None¶
- name: str = ''¶
- __post_init__()¶
- property d¶
Number of modulation dimensions.
- Type:
int
- resolve(lat, max_epsilon=3, tol=1e-06)¶
Fill in epsilon and G from the lattice, if not already given.
- Parameters:
lat (SuperspaceLattice) – Supplies the q-vectors.
max_epsilon (int) – Half-width of the integer search for epsilon.
tol (float) – Tolerance on the residual being a lattice vector.
- Returns:
A new operation with the internal part filled in.
- Return type:
- Raises:
ValueError – If R does not map the q-set onto itself.
- pyextal.superspace.symmetry.epsilon_for(R, q, max_epsilon=3, tol=1e-06)¶
Solve
R^T q_j = sum_k epsilon_jk q_k + G_jfor integers.A 3D operation is only a symmetry of a modulated structure if it permutes the Fourier module, which is what this checks. The search is a small exhaustive one over integer epsilon rows –
d <= 3and the entries are tiny, so there are at most a few hundred candidates.The decomposition is not unique when the q-vectors are dependent modulo the main lattice, which is exactly the 1T-TaS2 case: with three CDW arms satisfying
q1 + q2 + q3 = c*, any solution can be shifted by a multiple of that relation. The smallest one is returned – minimum|epsilon|first, then minimum|G|– which picks out the plain permutation withG = 0rather than some equivalent monster. Taking whichever candidate an unordered search happened to reach first would make the answer depend on iteration order.- Parameters:
R (array-like) – (3, 3) integer rotation on direct fractional coordinates.
q (array-like) – (d, 3) modulation wave vectors.
max_epsilon (int) – Half-width of the integer search per component.
tol (float) – How close the residual has to be to an integer vector.
- Returns:
(epsilon, G), shapes (d, d) and (d, 3).- Return type:
tuple[np.ndarray, np.ndarray]
- Raises:
ValueError – If some
R^T q_jcannot be written this way, meaning R is not a symmetry of the modulated structure.
- pyextal.superspace.symmetry.transform_reflection(op, H)¶
Apply a superspace operation to reflection indices.
From
R^T S(H) = (R^T h + G^T m) + sum_k (epsilon^T m)_k q_k, so the main part picks up theGcontribution and the satellite part transforms byepsilon^T. Valid for any G.- Parameters:
op (SuperspaceOperation) – Operation with its internal part resolved.
H (array-like) – (n, 3+d) integer superspace indices.
- Returns:
(n, 3+d) transformed indices.
- Return type:
np.ndarray
- Raises:
ValueError – If op has no internal part, or the widths disagree.
- pyextal.superspace.symmetry.expand_atoms(atoms, ops, lat, tol=1e-06)¶
Generate the symmetry-equivalent atoms and their modulation functions.
Under
(R | tau)an atom moves toR r + tauand its displacement field becomesu'(xbar) = R u(epsilon^-1 (xbar - tau_i)). Written out in harmonics, the index maps asn -> epsilon^-T nand the amplitudes mix by the phasephi = 2 pi n' . tau_i:A' = R (A cos phi + B sin phi) B' = R (-A sin phi + B cos phi)
- Parameters:
atoms (list[ModulatedAtom]) – The asymmetric unit.
ops (list[SuperspaceOperation]) – Operations, resolved or not.
lat (SuperspaceLattice) – Supplies the q-vectors for resolving.
tol (float) – Tolerance for recognising a duplicate position.
- Returns:
The expanded set, duplicates removed.
- Return type:
list[ModulatedAtom]
- Raises:
NotImplementedError – If any operation has a nonzero G. See the module docstring – list the structure in P1 instead.