deepmd.dpmodel.utils.spherical_harmonics
========================================

.. py:module:: deepmd.dpmodel.utils.spherical_harmonics

.. autoapi-nested-parse::

   Real spherical harmonics matching the e3nn convention used by SeZM.

   This module is a torch-free, pure-numpy replacement for the exact e3nn call
   used by the SeZM Lebedev S2-grid projection code
   (``deepmd/pt/model/descriptor/sezm_nn/projection.py``)::

       e3nn.o3.spherical_harmonics(
           list(range(lmax + 1)), vecs, normalize=True, normalization="norm"
       )

   Empirically verified e3nn convention facts (probed on basis vectors and
   random points, matching to machine precision):

   - Output layout: for each degree ``l`` from 0 to ``lmax``, a block of
     ``2l + 1`` components ordered ``m = -l, ..., +l``; component ``l*l + l + m``
     is the order-``m`` harmonic.
   - Axis convention: e3nn uses ``y`` as the polar axis. The ``l = 1`` block
     under ``normalization="norm"`` is exactly the unit input vector
     ``(x, y, z)`` in ``m = (-1, 0, +1)`` order, i.e. the standard z-polar real
     spherical harmonics evaluated with axes ``(x_s, y_s, z_s) = (z, x, y)``.
   - Phase convention: no Condon-Shortley phase. Negative orders carry
     ``sin(m * phi)``, positive orders ``cos(m * phi)`` with
     ``phi = atan2(x, z)``.
   - Normalization ``"norm"``: ``Y_lm = sqrt(4*pi / (2l+1)) * Y_lm^{orthonormal}``
     so that ``sum_m Y_lm(v)^2 = 1`` for every unit vector ``v``.
   - ``normalize=True``: input vectors are normalized internally before
     evaluation, making the output invariant to the input vector length.
   - Zero vectors: e3nn clamps the norm instead of dividing by zero, so a zero
     input vector yields ``[Y00, 0, 0, ...] = [1, 0, 0, ...]``. This module
     reproduces that exactly (no NaN, no runtime warning).

   ..
       !! processed by numpydoc !!


Functions
---------

.. autoapisummary::

   deepmd.dpmodel.utils.spherical_harmonics.real_spherical_harmonics


Module Contents
---------------

.. py:function:: real_spherical_harmonics(vecs: numpy.ndarray, lmax: int) -> numpy.ndarray

   
   Evaluate real spherical harmonics in the e3nn ``"norm"`` convention.

   Exactly matches ``e3nn.o3.spherical_harmonics(list(range(lmax + 1)),
   vecs, normalize=True, normalization="norm")`` (see module docstring).

   :Parameters:

       **vecs**
           Input vectors with shape ``(..., 3)``. They do not need to be
           normalized; vectors are normalized internally (e3nn
           ``normalize=True``). Zero vectors map to ``[1, 0, 0, ...]``
           exactly as in e3nn (which clamps the norm before dividing).

       **lmax**
           Maximum angular degree, any non-negative integer.



   :Returns:

       :obj:`np.ndarray <numpy.ndarray>`
           Real spherical harmonics with shape ``(..., (lmax + 1) ** 2)`` in
           float64, with each degree-``l`` block ordered ``m = -l, ..., +l``.











   ..
       !! processed by numpydoc !!

