httk.atomistic.cell =================== .. py:module:: httk.atomistic.cell .. autoapi-nested-parse:: The Cell class for httk-atomistic. Classes ------- .. autoapisummary:: httk.atomistic.cell.Cell Module Contents --------------- .. py:class:: Cell(basis: httk.core.VectorLike, scale: Any = 1, precision: Any = None, periodicity: Any = None) A crystallographic cell: its basis, the 3x3 matrix of cell vectors, held **exactly**. The lattice vectors are the rows of ``basis``. Internally a Cell factors that basis into a positive :class:`~httk.core.SurdScalar` ``scale`` times an ``unscaled_basis`` (a :class:`~httk.core.SurdVector` of shape ``(3, 3)``), with ``basis == scale * unscaled_basis``. The split lets an overall length factor be carried symbolically: a hexagonal cell of lattice parameter ``a`` and ratio ``c/a`` is the exact ``unscaled`` rows ``(1, 0, 0)``, ``(-1/2, sqrt(3)/2, 0)``, ``(0, 0, c/a)`` scaled by ``a`` — so the ``sqrt(3)`` stays exact regardless of ``a``. A cell built from an absolute basis simply has ``scale == 1``. Numbers embed exactly: rationals (and rational-valued floats) stay rational, and a :class:`~httk.core.SurdVector` basis keeps its radicals. Derived quantities are exact whenever the geometry is metric-rational (the crystallographic case): ``lengths`` come from :meth:`~httk.core.SurdVector.sqrt_of` of the rational squared row lengths, ``angles`` (degrees) from the exact reverse-Niven :meth:`~httk.core.SurdScalar.acos_degrees` where possible, ``volume`` from the exact determinant, and ``metric`` is the exact rational Gram matrix. When a squared length happens to be irrational, ``lengths``/``angles`` fall back to a deterministic rational approximation (documented per accessor). Exact accessors return vector objects — render them with ``.to_floats()`` (nested plain-float lists, numpy-free), ``float(...)`` on scalars, :meth:`numeric` (true numpy arrays), or a view of your choice. A cell also records its :attr:`periodicity`, which defaults to periodic in all three directions. Where it is not, the basis stops being purely a lattice and becomes partly a *coordinate frame*: see :attr:`periodicity` for what that means and :attr:`periodic_measure` for the quantity that replaces :attr:`volume`. .. py:property:: scale :type: httk.core.SurdScalar The overall (strictly positive) length factor, as an exact ``SurdScalar``. .. py:property:: unscaled_basis :type: httk.core.SurdVector The 3x3 cell vectors before applying ``scale``, as an exact ``SurdVector``. .. py:property:: basis :type: httk.core.SurdVector The 3x3 lattice vectors ``scale * unscaled_basis`` (one vector per row), exact. .. py:property:: precision :type: fractions.Fraction | None How precisely this basis was stated, as an absolute length, or ``None`` if unknown. In the same units as the basis itself, so for ordinary crystallographic data it is an ångström. Derived from the source's written digits and any stated uncertainty — a CIF cell edge of ``5.6402(3)`` is precise to ``3e-4``, not to the ``1e-4`` its four decimals alone would suggest. ``None`` means unknown, which is not the same as exact. It is what a cell built by hand or from a bare matrix reports. .. py:property:: periodicity :type: tuple[bool, bool, bool] Which of the three basis rows is a genuine lattice translation. ``(True, True, True)`` — the default, and what every ordinary crystal is. A slab is ``(True, True, False)``, a nanowire has one ``True``, and an isolated molecule is ``(False, False, False)``. A row flagged ``False`` is **not** a lattice vector. It is only a frame: it says what a fractional coordinate means along that direction, and nothing more. Coordinates there are unbounded — freely below 0 or above 1 — and are never wrapped into ``[0, 1)``. There is no vacuum and no padding involved, so making that row a unit vector simply means the coordinate along it *is* a length in the basis's units. This is the same notion, in the same order, as OPTIMADE's ``dimension_types``. .. py:property:: nperiodic_dimensions :type: int How many of the three directions are periodic, from 0 to 3. .. py:method:: numeric() -> httk.atomistic.numeric_cell.NumericCell A plain-numpy presentation of this cell (requires the ``httk-atomistic[numpy]`` extra). .. py:method:: metric() -> httk.core.SurdVector The exact Gram matrix ``matrix * matrix^T`` (rational for a metric-rational cell). .. py:property:: lengths :type: tuple[httk.core.SurdScalar, Ellipsis] The lengths of the three cell vectors (the scaled row norms). Exact via :meth:`~httk.core.SurdVector.sqrt_of` whenever the row's squared length is rational (the crystallographic case); otherwise a deterministic rational-approximation ``SurdScalar`` at ``_FALLBACK_PREC`` (the length would be a nested radical, outside the surd field). .. py:property:: angles :type: tuple[fractions.Fraction, Ellipsis] The cell angles ``(alpha, beta, gamma)`` in degrees, as exact ``Fraction`` values. Following the crystallographic convention, ``alpha`` is the angle between rows ``b`` and ``c``, ``beta`` between ``a`` and ``c``, and ``gamma`` between ``a`` and ``b``. Angles are scale-independent, so they are computed from the unscaled basis. The cosine is formed exactly in the surd field and reversed through the Niven table (:meth:`~httk.core.SurdScalar.acos_degrees`) for an exact answer; a non-Niven angle falls back to a deterministic :func:`~httk.core.exactmath.acos` at ``_FALLBACK_PREC``. .. py:property:: volume :type: httk.core.SurdScalar The cell volume, the exact absolute determinant of ``basis``. Defined only for a fully periodic cell, and raises :class:`ValueError` otherwise. For anything less, the determinant mixes real lattice vectors with frame vectors, so it is not a volume: it changes when a frame vector is rescaled, even though nothing about the material did. Any density or packing fraction derived from it would inherit that. See :attr:`periodic_measure` for the quantity that *is* defined. .. py:property:: periodic_measure :type: httk.core.SurdScalar The size of the repeating unit, whatever its dimension. A volume for a crystal, an area for a slab, a length for a nanowire. For a fully non-periodic cell there is no repeating unit and this is the empty product, ``1``, which is dimensionless rather than a length of any kind. Exact in the crystallographic case. The 3D case is the determinant and needs no square root at all; the 2D and 1D cases take the same square root that :attr:`lengths` does, so they are exact whenever the squared measure is a rational with a small radicand and fall back to a deterministic rational approximation otherwise.