Skip to main content

A Generic Particle+Grid Interface

Project description

GPGI

PyPI PyPI pre-commit.ci status Code style: black Ruff

A Generic Particle + Grid data Interface

This small Python library implements fundamental grid deposition algorithms to analyse (rectilinear) grid + particle datasets, with an emphasize on performance. Core algorithms are implemented as Cython extensions.

Table of Contents

Installation

python -m pip install --upgrade pip
python -m pip install gpgi

Supported applications

A rectilinear grid is defined as 1D arrays representing cell left edges in each directions. Note that the last point of such an array is interpreted as the right edge of the rightmost cell, so for instance, a 1D grid containing 100 cells is defined by 101 edges.

Particles are defined as points that live within the grid's bounds.

Deposition is the action of going from particle description to a grid description of a field. It is useful to analyze, compare and combine simulation data that exists in a combination of the two formalisms. This process is not reversible as it degrades information.

For instance, here's a simple overlay of a particle set (red dots) against a background that represents the deposited particle count.

This example illustrates the simplest possible deposition method "Particle in Cell", in which each particle contributes only to the cell that contains it.

More refined methods are also available.

Supported deposition methods

method name abreviated name order
Nearest Grid Point NGP 0
Cloud in Cell CIC 1
Triangular Shaped Cloud TSC 2

Supported geometries

geometry name axes order
cartesian x, y, z
polar radius, z, azimuth
cylindrical radius, azimuth, z
spherical radius, colatitude, azimuth
equatorial radius, azimuth, latitude

Time complexity

An important step in perfoming deposition is to associate particle indices to cell indices. This step is called "particle indexing". In directions where the grid is uniformly stepped (if any), indexing a particle is an O(1) operation. In the more general case, indexing is performed by bisection, which is a O(log(nx))) operation (where nx represents the number of cells in the direction of interest).

Usage

The API consists in a load function, which returns a Dataset object.

Load data

import numpy as np
import gpgi

nx = ny = 64
nparticles = 600_000

prng = np.random.RandomState(0)
ds = gpgi.load(
    geometry="cartesian",
    grid={
        "cell_edges": {
            "x": np.linspace(-1, 1, nx),
            "y": np.linspace(-1, 1, ny),
        },
    },
    particles={
        "coordinates": {
            "x": 2 * (prng.normal(0.5, 0.25, nparticles) % 1 - 0.5),
            "y": 2 * (prng.normal(0.5, 0.25, nparticles) % 1 - 0.5),
        },
        "fields": {
            "mass": np.ones(nparticles),
        },
    },
)

The Dataset object holds a grid and a particles attribute, which both hold a fields attribute for accessing their data. But more importantly, the Dataset has a deposit method to translate particle fields to the grid formalism.

Deposit Particle fields on the grid

particle_mass = ds.deposit("mass", method="nearest_grid_point")  # or "ngp" for shorts

Visualize In this example we'll use matplotlib for rendering, but note that matplotlib is not a dependency to gpgi

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.set(aspect=1, xlabel="x", ylabel="y")

im = ax.pcolormesh(
    "x",
    "y",
    particle_mass.T,
    data=ds.grid.cell_edges,
    cmap="viridis",
)
fig.colorbar(im, ax=ax)

The example script given here takes about a second (top to bottom).

Supplying arbitrary metadata

new in gpgi 0.4.0

Dataset objects have a special attribute metadata which is a dictionary with string keys. This attribute is meant to hold any special metadata that may be relevant for labelling or processing (e.g. simulation time, author, ...). Metadata can be supplied at load time as

ds = gpgi.load(
    geometry="cartesian",
    grid=...,
    particles=...,
    metadata={"simulation_time": 12.5, "author": "Clément Robert"}
)

Boundary conditions

new in gpgi 0.5.0

With CIC and TSC deposition, particles contribute to cells neighbouring the one that contains them. For particles that live in the outermost layer of the domain, this means some of their contribution is lost. This behaviour corresponds to the default 'open' boundary condition, but gpgi has builtin support for more conservative boundary conditions.

Boundary conditions can selected per field, per axis and per side. Builtin recipes all perform linear combinations of ghost layers (same-side and opposite side) and active domain layers (same-side and opposite side), and replace the same-side active layer with the result.

User-selected boundary conditions take the form of an optional argument to Dataset.deposit, as dictionnary with keys being axes names, and values being 2-tuples of boundary conditions names (for left and right side respectively). For instance, here's how one would require periodic boundary conditions on all axes:

ds.deposit(
    "mass",
    method="cic",
    boundaries={
        "x": ("periodic", "periodic"),
        "y": ("periodic", "periodic"),
    }
)

Unspecified axes will use the default 'open' boundary.

Builtin recipes

boundary conditions description conservative ?
open (default) no special treatment no
periodic add opposite ghost layer to the active domain yes
wall add same-side ghost layer to the active domain yes
antisymmetric substract same-side ghost layer from the active domain no

Define custom recipes

gpgi's boundary recipes can be customized. Let's illustrate this feature with a simple example. Say we want to fix the value of the deposited field in some outer layer. This is done by defining a new function on the user side:

def ones(
    same_side_active_layer,
    same_side_ghost_layer,
    opposite_side_active_layer,
    opposite_side_ghost_layer,
    weight_same_side_active_layer,
    weight_same_side_ghost_layer,
    weight_opposite_side_active_layer,
    weight_opposite_side_ghost_layer,
    side,
    metadata,
):
   return 1.0

where all first eight arguments are numpy.ndarray objects with the same shape (which includes ghost padding !), to which the return value must be broadcastable, side can only be either "left" or "right", and metadata is the special Dataset.metadata attribute. Not all arguments need be used in the body of the function, but this signature is required.

The method must then be registered as a boundary condition recipe as

ds.boundary_recipes.register("ones", ones)

where the associated key (here "ones") is arbitrary. The recipe can now be used exactly as builtin ones, and all of them can be mixed arbitrarily.

ds.deposit(
    "mass",
    method="cic",
    boundaries={
        "x": ("ones", "wall"),
        "y": ("periodic", "periodic"),
    }
)

Note that all first eight arguments in a boundary recipe function should represent an extensive physical quantity (as opposed to intensive). When depositing an intensive quantity u, a weight field w should be supplied (see next section), in which case, the first four arguments represent u*w and the following four represent w, so that u can still be obtained within the function as a ratio if needed.

Weight fields (Depositing intensive quantities)

new in gpgi 0.7.0

Fundamentally, deposition algorithms construct on-grid fields by performing summations. An implication is that the physical quantities being deposited are required to be extensive (like mass or momentum). Intensive quantities (like velocity or temperature) require additional operations, and necessitate the use of an additional weight field.

This section provides showcases their usage. For a detailled explanation of the deposition algorithm for intensive quantities, see Deposition algorithm.

In order to deposit an intensive field (e.g., vx), an additional weight_field argument must be provided as

ds.deposit(
    "vx",
    method="cic",
    boundaries={
        "y": ("periodic", "periodic"),
        "x": ("antisymmetric", "antisymmetric"),
    },
    weight_field="mass",
    weight_field_boundaries={
        "y": ("periodic", "periodic"),
        "x": ("open", "open"),
    },
)

Boundary recipes may be also associated to the weight field with the weight_field_boundaries argument. This arguments becomes required if boundaries and weight_field are both provided.

Call help(ds.deposit) for more detail.

Deposition algorithm

This section provides details on the general deposition algorithm, as implemented in gpgi.

Without loss of generality, we will illustrate how an intensive field (v) is deposited, since this case requires the most computational steps. As it happens, depositing an extensive field (w) separately is actually part of the algorithm.

Definitions

  • v is an intensive field that we want to deposit on the grid
  • w is an extensive field that will be used as weights
  • u = v * w is an extensive equivalent to v (conceptually, if v is a velocity and w is a mass, u corresponds to a momentum)

u(i), v(i) and w(i) are defined for each particle i.

We note U(x), V(x) and W(x) the corresponding on-grid fields, where V(x) is the final output of the algorithm. These are defined at grid cell centers x, within the active domain.

Last, we note U'(x), V'(x) and W'(x) the raw deposited fields, meaning no special treatment is applied to the outermost layers (boundary conditions). These are defined at grid cell centers, including one ghost layer that will be used to apply boundary conditions.

Algorithm

  1. W' and U' are computed as
W'(x) = Σ c(i,x) w(i)
U'(x) = Σ c(i,x) w(i) v(i)

where c(i,x) are geometric coefficients associated with the deposition method. Taking the nearest grid point (NGP) method for illustration, c(i,x) = 1 if particle i is contained in the cell whose center is x, and c(i,x) = 0 elsewhere.

  1. boundary conditions are applied
W(x) = W_BCO(W', 1, metadata)
U(x) = U_BCO(U', W', metadata)

where W_BCO and U_BCO denote arbitrary boundary condition operators associated with W and U respectively, and which take 3 arguments, representing the field to be transformed, its associated weight field and a wildcard metadata argument which may contain any additional data relevant to the operator.

Note 1 is used a placeholder "weight" for W, for symmetry reasons: all boundary condition operators must expose a similar interface, as explained in Define custom recipes.

  1. Finally, V(x) is obtained as
V(x) = (U/W)(x)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gpgi-0.10.0.tar.gz (352.1 kB view details)

Uploaded Source

Built Distributions

gpgi-0.10.0-cp311-cp311-win_amd64.whl (203.4 kB view details)

Uploaded CPython 3.11 Windows x86-64

gpgi-0.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

gpgi-0.10.0-cp311-cp311-macosx_10_9_x86_64.whl (241.1 kB view details)

Uploaded CPython 3.11 macOS 10.9+ x86-64

gpgi-0.10.0-cp310-cp310-win_amd64.whl (205.4 kB view details)

Uploaded CPython 3.10 Windows x86-64

gpgi-0.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

gpgi-0.10.0-cp310-cp310-macosx_10_9_x86_64.whl (245.0 kB view details)

Uploaded CPython 3.10 macOS 10.9+ x86-64

gpgi-0.10.0-cp39-cp39-win_amd64.whl (207.0 kB view details)

Uploaded CPython 3.9 Windows x86-64

gpgi-0.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

gpgi-0.10.0-cp39-cp39-macosx_10_9_x86_64.whl (243.5 kB view details)

Uploaded CPython 3.9 macOS 10.9+ x86-64

gpgi-0.10.0-cp38-cp38-win_amd64.whl (207.4 kB view details)

Uploaded CPython 3.8 Windows x86-64

gpgi-0.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

gpgi-0.10.0-cp38-cp38-macosx_10_9_x86_64.whl (240.5 kB view details)

Uploaded CPython 3.8 macOS 10.9+ x86-64

File details

Details for the file gpgi-0.10.0.tar.gz.

File metadata

  • Download URL: gpgi-0.10.0.tar.gz
  • Upload date:
  • Size: 352.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.1

File hashes

Hashes for gpgi-0.10.0.tar.gz
Algorithm Hash digest
SHA256 efbe92930859a5897c496d70116084c871d7cc0833546fbee57c6e487e359abc
MD5 dfb01742e2d48938f9f49961910e84dc
BLAKE2b-256 103e0eea2d07731f8722c5e8aa92a444608aa2f9b6f3c9775e95cefb474d0cbc

See more details on using hashes here.

File details

Details for the file gpgi-0.10.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: gpgi-0.10.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 203.4 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.1

File hashes

Hashes for gpgi-0.10.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 5394d9b90a7d50dcb30ad0ddc5034ad31d0dd13c2b2d69e2ab7ee5474f3adbfb
MD5 f8235428747e88e3f1024e37b4b50fbf
BLAKE2b-256 cb822bdf812b21cbcba6512c0848625ab9ae0c6a8e70fd0639677714f4da8f69

See more details on using hashes here.

File details

Details for the file gpgi-0.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for gpgi-0.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 58f3d3497d2bfad4830c3a8ea45a4e6de930ca64d9b45f42deee23499253e559
MD5 6354cb7150306b9419ea2903b83f3d95
BLAKE2b-256 7b0d6467e9b55dffbcc3de9004e884746b9794b0dd31ec2276f148b12a220250

See more details on using hashes here.

File details

Details for the file gpgi-0.10.0-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for gpgi-0.10.0-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 2522f93956e71e129f35c5b39817091866d26284ea2aa6045bada03948057fee
MD5 b6d3bfa9808a04cd540f575c13629f48
BLAKE2b-256 e7db317e012b1171244a09724882df7d1b004dbea88da8115ad427731cb6af43

See more details on using hashes here.

File details

Details for the file gpgi-0.10.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: gpgi-0.10.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 205.4 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.1

File hashes

Hashes for gpgi-0.10.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 4763b53b0930608df55f71a7806fc0599908ea54209036b850da6de79cc8d1f7
MD5 2dd13a109527afeeda991a98040a71b2
BLAKE2b-256 816e30959b853ffa94fc592c63a4c4d3b43e2390c5fc9f0d53235aa1686f518f

See more details on using hashes here.

File details

Details for the file gpgi-0.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for gpgi-0.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 020e1e28faef6d795c12f5dee6ef19e25fdbe63dc4d309702d6d289b0fe10798
MD5 7d77e909329aea265cb511019252fe85
BLAKE2b-256 07173fb90f35ab959f48d0b787c3eda384919dc8926ad6c98389b4785d8ee95e

See more details on using hashes here.

File details

Details for the file gpgi-0.10.0-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for gpgi-0.10.0-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 522e7524698eccaeef90572da50e52ea2b1344f44a6c05dc6bb1a7e5638dd0d2
MD5 279d06bfc135e008c0cef83e34edea46
BLAKE2b-256 651216dc9b1235c5fc6f95015b6dcb26d517a845cac070c422b446246fdc102f

See more details on using hashes here.

File details

Details for the file gpgi-0.10.0-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: gpgi-0.10.0-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 207.0 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.1

File hashes

Hashes for gpgi-0.10.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 a8de37dba6a6d4194dbdc65bd68005276fafd12b6a4970b67c591e0dc2b6c07a
MD5 48c1bf5282a128be32c0de08ce80cde8
BLAKE2b-256 0ebfb626e1c64aca8114d8f2e4af93ab97a4092a8d7cb6a05e3a227c1de10baa

See more details on using hashes here.

File details

Details for the file gpgi-0.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for gpgi-0.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 81ff11afd69d3b90346b197a355aaa8f986c6d4ac9ea6d6411621cbbe770b432
MD5 b67c399de597164888110899ef7960d9
BLAKE2b-256 d71e5e2518a4064be5d7fde846fbdc2e84fb41dd06eebb94a6fd03baf0ea6645

See more details on using hashes here.

File details

Details for the file gpgi-0.10.0-cp39-cp39-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for gpgi-0.10.0-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 32d38d6036631677fb391ab621420522e6274f47707d02a49e51e8d1316ce195
MD5 feb2989e6d46d7e14d35459ca489b58a
BLAKE2b-256 46a6437a04ddf2c80cd1583c99e8758113844a449f321d832a185b97f2ce987b

See more details on using hashes here.

File details

Details for the file gpgi-0.10.0-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: gpgi-0.10.0-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 207.4 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.1

File hashes

Hashes for gpgi-0.10.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 31683fd0496389e6892aeab2ee2f95672f892a81fb10803a4dc6cf6d925dc059
MD5 37b13953b3e69c220e22c31ec9302720
BLAKE2b-256 3191ffe10298f6b6edee0ac7bfd18ea900350e8460bc843d6c29bbfe55fa5e0b

See more details on using hashes here.

File details

Details for the file gpgi-0.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for gpgi-0.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 150a8e9fc2dac130344b40efcfe7d6e60c026d0f61e5630aca7e4d491dcd0d3a
MD5 deda8a7cd19f7886cd3ece14ea779901
BLAKE2b-256 24e370f3ad73807bd4f4f625275de6bc1b5a56ad90d9d2eda9f09961b6414a69

See more details on using hashes here.

File details

Details for the file gpgi-0.10.0-cp38-cp38-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for gpgi-0.10.0-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 f927d03670d76ae64f775391298a42ceff35ef1669ade0d43c9854740844a228
MD5 f8d4d32b0ff03833e34d126bf6ea08d1
BLAKE2b-256 4d51b4287bbbbba8d4e483a94b83e344b160e8b247b0a92c72fbf461218bd2d1

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page