Skip to content

Grid🔗

This class manages the grids (real and k-space) needed for the field theoretic simulations. It stores and pre-computes useful quantities for the modified diffusion equation and integrators to use elsewhere.

Parameters:

Name Type Description Default
box_length Tuple[float, ...]

Lengths of the simulation box along each axis \(L_i\).

required
grid_spec Tuple[int, ...]

Number of lattice points along each axis \(M_{Li}\).

required

Attributes:

Name Type Description
grid_spec Tuple[int, ...]

Number of lattice points along each axis \(M_{Li}\).

ndims int

Dimension of the system \(d\).

l cp.ndarray of float

Lengths of the simulation box along each axis \(L_i\).

dl cp.ndarray of float

Lengths of the unit cell along each axis \(\Delta L_i\).

V float

Total box volume \(V\).

dV float

Volume of the unit cell \(dV\).

grid cp.ndarray of float

Real-space coordinates of each grid point. Shape is (\(d\), \(N_x\), \(N_y\), ...). grid[0] is a grid of all x-coordinates, same for other dimensions

kgrid cp.ndarray of float

Grid of (x, ...) k Fourier-transformed positions at each k point.

k1 cp.ndarray of float

Grid of (x, ...) L1 norm distances at each k point.

k2 cp.ndarray of float

Grid of (x, ...) L2 norm distances at each k point.

Raises:

Type Description
ValueError

Raises error if the box length is not a tuple

Source code in polycomp/grid.py
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
class Grid:
    """
    This class manages the grids (real and k-space) needed for the field theoretic
    simulations. It stores and pre-computes useful quantities for the
    modified diffusion equation and integrators to use elsewhere.

    Parameters
    ----------

    box_length
        Lengths of the simulation box along each axis $L_i$.
    grid_spec
        Number of lattice points along each axis $M_{Li}$.

    Attributes
    ----------

    grid_spec : Tuple[int, ...]
        Number of lattice points along each axis $M_{Li}$.
    ndims : int
        Dimension of the system $d$.
    l : cp.ndarray of float
        Lengths of the simulation box along each axis $L_i$.
    dl : cp.ndarray of float
        Lengths of the unit cell along each axis $\\Delta L_i$.
    V : float
        Total box volume $V$.
    dV : float
        Volume of the unit cell $dV$.
    grid : cp.ndarray of float
        Real-space coordinates of each grid point.
        Shape is ($d$, $N_x$, $N_y$, ...). grid[0] is a grid of all
        x-coordinates, same for other dimensions
    kgrid : cp.ndarray of float
        Grid of (x, ...) k Fourier-transformed positions at each k point.
    k1 : cp.ndarray of float
        Grid of (x, ...) L1 norm distances at each k point.
    k2 : cp.ndarray of float
        Grid of (x, ...) L2 norm distances at each k point.

    Raises
    ------

    ValueError
        Raises error if the box length is not a tuple
    """

    def __init__(
        self, box_length: Tuple[float, ...], grid_spec: Tuple[int, ...]
    ) -> None:
        super().__init__()

        self.grid_spec = grid_spec
        self.ndims = len(self.grid_spec)
        if isinstance(box_length, tuple):
            self.l = cp.array(box_length)
        else:
            raise ValueError("box_length is not tuple")
        self.update_l(self.l)

    def update_l(self, new_l: ArrayLike) -> None:
        """
        This function reconstructs the grid, using the previous gridding but for a new
        box size. Performs required operations for all dependent parameters to be
        correctly set for new grid.

        Parameters
        ----------

        new_l
            New box lengths $L_i$ to be assigned

        """

        self.l = cp.array(new_l)

        # Total volume
        self.V = cp.prod(cp.array(self.l))

        # Grid of real positions
        self.grid = cp.asarray(
            cp.meshgrid(
                *[
                    cp.linspace(0, l, n)
                    for n, l in zip(
                        self.grid_spec,
                        self.l * (1 - 1 / cp.array(self.grid_spec)),
                    )
                ]
            )
        )

        # Grid of k positions
        self.kgrid = cp.asarray(
            cp.meshgrid(
                *[
                    2
                    * cp.pi
                    / l
                    * cp.concatenate(
                        (cp.arange(0, n / 2 + 1), cp.arange(-n / 2 + 1, 0)),
                        axis=None,
                    )
                    for n, l in zip(self.grid_spec, self.l)
                ]
            )
        )

        self.k1 = cp.sum(self.kgrid, axis=0)
        self.k2 = cp.sum(self.kgrid**2, axis=0)
        self.dV = self.V / self.k2.size
        self.dl = self.l / cp.array(self.grid_spec)

        return

Functions🔗

update_l(new_l: ArrayLike) -> None 🔗

This function reconstructs the grid, using the previous gridding but for a new box size. Performs required operations for all dependent parameters to be correctly set for new grid.

Parameters:

Name Type Description Default
new_l ArrayLike

New box lengths \(L_i\) to be assigned

required
Source code in polycomp/grid.py
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
def update_l(self, new_l: ArrayLike) -> None:
    """
    This function reconstructs the grid, using the previous gridding but for a new
    box size. Performs required operations for all dependent parameters to be
    correctly set for new grid.

    Parameters
    ----------

    new_l
        New box lengths $L_i$ to be assigned

    """

    self.l = cp.array(new_l)

    # Total volume
    self.V = cp.prod(cp.array(self.l))

    # Grid of real positions
    self.grid = cp.asarray(
        cp.meshgrid(
            *[
                cp.linspace(0, l, n)
                for n, l in zip(
                    self.grid_spec,
                    self.l * (1 - 1 / cp.array(self.grid_spec)),
                )
            ]
        )
    )

    # Grid of k positions
    self.kgrid = cp.asarray(
        cp.meshgrid(
            *[
                2
                * cp.pi
                / l
                * cp.concatenate(
                    (cp.arange(0, n / 2 + 1), cp.arange(-n / 2 + 1, 0)),
                    axis=None,
                )
                for n, l in zip(self.grid_spec, self.l)
            ]
        )
    )

    self.k1 = cp.sum(self.kgrid, axis=0)
    self.k2 = cp.sum(self.kgrid**2, axis=0)
    self.dV = self.V / self.k2.size
    self.dl = self.l / cp.array(self.grid_spec)

    return