Skip to main content

A Generic Particle+Grid Interface

Project description

GPGI

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

Fast particle deposition at post-processing time

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.

GPGI stands for Generic Particle + Grid data Interface

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.

Builtin deposition methods

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

new in gpgi 0.12 User-defined alternative methods may be provided to Dataset.deposit as method=my_func. Their signature need to be compatible with gpgi.types.DepositionMethodT.

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.12.0.tar.gz (351.9 kB view details)

Uploaded Source

Built Distributions

gpgi-0.12.0-cp311-cp311-win_amd64.whl (204.5 kB view details)

Uploaded CPython 3.11 Windows x86-64

gpgi-0.12.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.12.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.12.0-cp310-cp310-win_amd64.whl (206.4 kB view details)

Uploaded CPython 3.10 Windows x86-64

gpgi-0.12.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.12.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.12.0-cp39-cp39-win_amd64.whl (208.1 kB view details)

Uploaded CPython 3.9 Windows x86-64

gpgi-0.12.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.12.0-cp39-cp39-macosx_10_9_x86_64.whl (243.7 kB view details)

Uploaded CPython 3.9 macOS 10.9+ x86-64

gpgi-0.12.0-cp38-cp38-win_amd64.whl (208.4 kB view details)

Uploaded CPython 3.8 Windows x86-64

gpgi-0.12.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.12.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.12.0.tar.gz.

File metadata

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

File hashes

Hashes for gpgi-0.12.0.tar.gz
Algorithm Hash digest
SHA256 913242ec21a2adde888462cb72f96fb2ca104ce8df9f1d85909f96e5bd24aee9
MD5 69973740e5e19d0b5e5ea1c748d1274f
BLAKE2b-256 c8c7d593b7d2a904a475c3b225d6b7c4d93024f4acc8a43bc34a0176aeaf4d0d

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for gpgi-0.12.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 4a94c95690f837574e9ab01647c375474914d4e3435bd596a927d08835d7d556
MD5 e632aaa64ef1bee2d9b062c2a20973b1
BLAKE2b-256 afa71783e749024d5fa27b25744b75760a95fdf50e63332971d9dce3144432e2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for gpgi-0.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6d99372d14d88e88a93a659b88673f958811340e6f7255ca7f662c4beb824c95
MD5 97937315dfa1d64a56dc68409d05aa26
BLAKE2b-256 1ece682c2240babe16311ea558ac9fa1e5be3374e67a5f5e24681a9c71fa50c4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for gpgi-0.12.0-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 48861e63582313203c98c01a9cb4ffbb0e072a9c757b6d55f0731d6084a64c76
MD5 b1f7c1f9aa5d5819f2f1a8d33c7da4ab
BLAKE2b-256 a7e3c071036d10252310cbec1a327e29bd75975fcbb214c257ca69bf1e1e989f

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for gpgi-0.12.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 3fc493f7ecf738b80fe0a880b0e4e091101a812f1270be3e9e7ac00aa1d93c27
MD5 a103e6fa11505dc212697e34bf6ac73f
BLAKE2b-256 e67e461757ceb0c25e61a70470b7473dee4fe87e213b0a3bd26244fb98404eee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for gpgi-0.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 428fe17eddfde2c71803695dade560bdae9605f37d5afe878950b77547e8d8ae
MD5 da03c378c733530f5636b999a9c53002
BLAKE2b-256 722281912acb5866d6b440f331d6a784d96d4d21d5816c99b4f02804d6469558

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for gpgi-0.12.0-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 28aa58efcc8424243a848a4e2ebd3dca91c51fc12aedb8228f2762f0cff728da
MD5 0cfc6f4aee5b9d7d85b94362be6dbf9b
BLAKE2b-256 dba91371dfe59f6419a5bce9e93053d3196889b114f2c0ab9266fcfaef31d8a3

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for gpgi-0.12.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 ae0050e1ff5ebd61789fd2f78284b376b4530e81eee783805af94f9d1d911c2a
MD5 1a1e79c935f41df6b951ab1e361417c2
BLAKE2b-256 ed7985c8f665e36948e60e3acfa61e04e4b94b79796874c9515ee2c10352f820

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for gpgi-0.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a3f6f6ebd7ee6b8a78f5fee60d6c1671abc86be9156130cb6196d87a67251919
MD5 fbc8f92ec7b0febc5a79d0fd6db4060e
BLAKE2b-256 8e8d9a6ad6da4485ab7fd5b3ca2aeb2f1a5c92f9d408eb3b26068d4c610aa166

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for gpgi-0.12.0-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 c10fe76fb13da08b4355d3f2f7b0128ffe122ea50bc382f69cd73622f45b03a4
MD5 f29cfc08544944458f0127f7e9379086
BLAKE2b-256 8a049f48cb00015643d33c52caba901ba50bbb15ceeda5d8d41c5a29cd80e6b5

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for gpgi-0.12.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 72d1ea0412595e92476cec9a04282a65493fdc759e41be78210ba389843d17f7
MD5 6be516fea7748c35715272cfa342cdee
BLAKE2b-256 def3efd8d317b7c646ee65132833b5c83c2fc6e3979922f482732ba39607d1fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for gpgi-0.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 51f0b7b291a8771a9eb15a13554f7e4a12eb59407e184a5c13108f583c8cfab0
MD5 2cec29f85f181f3db45a2181c5617782
BLAKE2b-256 7394a1c23a998e6522df88562b87974b3a8cb69c4ac67dbabb205e63e9e4eee9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for gpgi-0.12.0-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 c282441c8028baf34fe53f2fff57287d50028cc811da7290d6e56944179bb008
MD5 4583dc252a18e10c81f9a319d9d6eddf
BLAKE2b-256 0545b6a5cbdcf5a11a826ab1f5bd2fafa2c478d8228c03cf7d41176e86ae7adc

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