Source code for pde.grids.coordinates.cartesian

"""
.. codeauthor:: David Zwicker <david.zwicker@ds.mpg.de>
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import numpy as np

from .base import CoordinatesBase

if TYPE_CHECKING:
    from numpy.typing import ArrayLike

    from ...tools.typing import FloatingArray


[docs] class CartesianCoordinates(CoordinatesBase): """N-dimensional Cartesian coordinates.""" _objs: dict[int, CartesianCoordinates] = {} def __new__(cls, dim: int): # cache the instances for each dimension if dim not in cls._objs: cls._objs[dim] = super().__new__(cls) return cls._objs[dim] def __getnewargs__(self): return (self.dim,) def __init__(self, dim: int): """ Args: dim (int): Dimension of the Cartesian coordinate system """ if dim <= 0: msg = "`dim` must be positive integer" raise ValueError(msg) self.dim = dim if self.dim <= 3: self.axes = list("xyz"[: self.dim]) else: self.axes = [chr(97 + i) for i in range(self.dim)] self.coordinate_limits = [(-np.inf, np.inf)] * self.dim def __repr__(self) -> str: """Return instance as string.""" return f"{self.__class__.__name__}(dim={self.dim})" def __eq__(self, other): return self.__class__ is other.__class__ and self.dim == other.dim def _pos_to_cart(self, points: FloatingArray) -> FloatingArray: return points def _pos_from_cart(self, points: FloatingArray) -> FloatingArray: return points def _mapping_jacobian(self, points: FloatingArray) -> FloatingArray: jac = np.zeros((self.dim, self.dim, *points.shape[:-1])) jac[range(self.dim), range(self.dim)] = 1 return jac def _volume_factor(self, points: FloatingArray) -> ArrayLike: return np.ones(points.shape[:-1]) def _cell_volume(self, c_low: FloatingArray, c_high: FloatingArray): return np.prod(c_high - c_low, axis=-1) def _scale_factors(self, points: FloatingArray) -> FloatingArray: return np.ones_like(points) def _basis_rotation(self, points: FloatingArray) -> FloatingArray: return np.eye(self.dim)