pyextal.jaxMultipole.harmonics¶
Density-normalised real spherical harmonics and their site-symmetry constraints.
Convention¶
The angular functions are XD’s (Hansen & Coppens 1978; Paturle & Coppens 1988):
i.e. associated Legendre functions without the Condon-Shortley phase times
cos m phi (+) or sin m phi (-), written as polynomials in the
Cartesian components of a unit vector. M_lm makes them density-normalised:
int |d_lm| dOmega = 2 for l > 0 and d_00 = 1/(4 pi). A population
P_lm is then roughly the number of electrons moved from the negative lobes
to the positive ones, and the cubic combination comes out as the familiar
P44+ = 0.74045 P40.
M_lm is computed once, from 1-D integrals split at the roots of the
Legendre polynomial, so it carries no grid error.
Coefficients are ordered l = 0..lmax, within l as m = 0, 1+, 1-, 2+,
2-, ..., and labelled P00, P10, P11+, P11-, P20, ....
Symmetry¶
A rotation (proper or improper) R of the density, rho'(r) = rho(R^T r),
mixes the coefficients of one l by a (2l+1) square matrix Q(R)
(real_wigner()). It is obtained by least squares from the functions
evaluated at random directions rather than from closed-form Wigner matrices, so
improper operations are handled without special cases (inversion gives
(-1)^l). A site symmetry S allows exactly the populations with Q(R) P =
P for every R in S, and allowed_multipole_basis() returns the
null space of the stacked I - Q(R), canonicalised to reduced row-echelon
form in the order above. In a frame chosen as Kurki-Suonio’s index-picking rules
choose it (z along the main axis, x along a 2-fold axis or mirror normal) that
basis is the usual list of individual P_lm, plus ties like the cubic one.
Functions¶
|
|
|
|
|
Position of |
|
|
|
Density-normalised real harmonics at directions |
|
The matrix |
|
Populations of order |
|
|
|
Number of invariant functions of order |
Module Contents¶
- pyextal.jaxMultipole.harmonics.n_functions(lmax)¶
- pyextal.jaxMultipole.harmonics.labels(lmax)¶
('P00', 'P10', 'P11+', 'P11-', ...)up tolmax.
- pyextal.jaxMultipole.harmonics.index(l, m=0, sign='+')¶
Position of
P_lm+/-in the flat coefficient vector.
- pyextal.jaxMultipole.harmonics.normalisation(l, m)¶
M_lm, the divisor that density-normalisesc_lm.
- pyextal.jaxMultipole.harmonics.dlm(u, lmax=4, xp=jnp)¶
Density-normalised real harmonics at directions
u.- Parameters:
u (array-like) –
(..., 3)vectors in the local Cartesian frame; they need not be unit length. The zero vector givesd_00and zeros, which is harmless because everyl > 0radial transform vanishes atk = 0.lmax (int) – Highest order.
xp (module) –
jax.numpy(default, differentiable) ornumpy– for constants (symmetry matrices, precomputed geometry), where NumPy is exact float64 and avoids dispatching hundreds of tiny operations to an accelerator.
- Returns:
(..., (lmax+1)^2)inlabels()order.- Return type:
array
- pyextal.jaxMultipole.harmonics.real_wigner(R, l)¶
The matrix
QwithP' = Q Pfor the density rotated byR.- Parameters:
R (np.ndarray) – (3, 3) orthogonal matrix, proper or improper, acting on Cartesian vectors in the frame the harmonics are defined in.
l (int) – Order.
- Returns:
(2l+1, 2l+1), orthogonal.- Return type:
np.ndarray
- pyextal.jaxMultipole.harmonics.allowed_multipole_basis(rots, l, tol=1e-08)¶
Populations of order
la site symmetry leaves free.- Parameters:
rots (np.ndarray) –
(m, 3, 3)site-symmetry operations as Cartesian matrices in the atom’s local frame.l (int) – Order.
tol (float) – Singular-value cutoff.
- Returns:
(2l+1, nfree). Columns are in reduced row-echelon form: each starts with a 1 at its own leading coefficient, and a tie shows up as further non-zero entries ([1, 0, ..., 0.74045, 0, ...]for the cubic l = 4 function).- Return type:
np.ndarray
- pyextal.jaxMultipole.harmonics.rotation_angle(R)¶
(angle, proper)of an orthogonal matrix; improper ones as-R.
- pyextal.jaxMultipole.harmonics.character_count(rots, l)¶
Number of invariant functions of order
l, from group characters.(1/|G|) sum chi_l(R)withchi_l = sin((l+1/2) phi) / sin(phi/2), times(-1)^lfor improper operations. Independent of the projector route, so it serves as a check ofallowed_multipole_basis().