pyloggrid.LogGrid.Grid

Class that directly handles the log grid & related maths

Module Contents

Classes

Grid

Main class that handles the log grid

Maths

Functions to perform maths on log grids

Physics

Computes a few classical physical properties

Functions

_setup_convolver_c(→ None)

Setup the imported C function. Important to avoid segfaults.

_setup_convolver_c(convolver_c) None

Setup the imported C function. Important to avoid segfaults. We keep the convolver as an argument to allow importing this function elsewhere

class Grid(D: int, l_params: dict[str, float | bool], N_points: int, fields_name: list[str], k_min: float = None, k0: bool = False, n_threads: int = None)

Main class that handles the log grid

init_fields() None

Creates the arrays corresponding to the field names

get_l_from_params() float

Sets the grid spacing from the grid’s parameters.

Returns:

the grid spacing

See pyoggrid.LogGrid.Framework.Solver for more information.

Reference:

Campolina & Mailybaev 2020, Fluid dynamics on logarithmic lattices

generate_points(k_min: float) tuple[ndarray, ndarray, ndarray, ndarray]

Create the grid’s wavevector arrays

Parameters:

k_min – the minimum wavevector

Returns:

(array of wave vectors along X axis [N,], logmean of array of wave vectors along X axis [N,], array of wave vectors [D, N, (2N, 2N)], array of wave vector modulus [N, (2N, 2N)])

load_fields(fields: dict[str, ndarray]) Grid

Load fields from a grid of another dimension. If the new grid is smaller, discard outer fields. If bigger, set new fields to 0.

Parameters:

fields – fields from the previous grid. fields names must correspond for both grids, as well as k_min.

enforce_grid_symmetry() None

Force the f(-k)=f(k).conj symmetries along 0 axes for all fields

field(*args) list[ndarray] | ndarray

get fields by name

to_new_size(fields: dict) Grid

return a new grid with the same parameters as this one but a new size

Parameters:

fields – the new fields

to_new_size_empty(N_points: int) Grid

return a new grid with the same parameters as this one but a new size, empty

Parameters:

N_points – the new size

class Maths(grid: Grid, n_threads: int = 0)

Functions to perform maths on log grids

convolve_batch

Convolve a list of convolutions at once. More efficient that calling convolve() several times. Use as convolve_batch([(f0,g0), (f1,g1), ...])

Type:

Callable

property dx: ndarray

x-derivative

property dy: ndarray

y-derivative

property dz: ndarray

z-derivative

property d2x: ndarray

2nd x-derivative

property d2y: ndarray

2nd y-derivative

property d2z: ndarray

2nd z-derivative

property rot2D_inv: ndarray

Inverse rotational for 2D fields, assuming div = 0

property laplacian: ndarray

laplacian

property laplacian_inv: ndarray

inverse laplacian

cached_conv_kernel
generate_convolution_kernel() tuple[ndarray, ndarray, ndarray, ndarray, ndarray, ndarray]

Generate the convolution kernel (who interacts with who) for log grid convolutions

Returns:

(kernel offsets, kernel signs) | signs are used to determine when to take the complex conjugate (+1 = normal, -1 = conjugate)

convolve(f: ndarray, g: ndarray) ndarray

Convolve the two arrays.

Returns:

the convolved array

_convolve_batch_V_inner(fgs: list[tuple[ndarray, ndarray]], V: int) ndarray

Inner function for <_convolve_batch_V>. Convolves in batch V couples, calling the corresponding convolve_list_batch_V function in C.

_convolve_batch_V(fgs: list[tuple[ndarray, ndarray]]) ndarray

from couples ((f0, g0), (f1, g1), ...), computes their convolution

Returns:

the convolved arrays f0*g0, f1*g1, etc.

_convolve_batch_list_slower(fgs: list[tuple[ndarray, ndarray]]) ndarray

from couples ((f0, g0), (f1, g1), ...), computes their convolution using batched OMP-supported convolutions

Returns:

the convolved arrays f0*g0, f1*g1, etc.

_convolve_batch_list(fgs: list[tuple[ndarray, ndarray]]) Iterable[ndarray]

from couples ((f0, g0), (f1, g1), ...), computes their convolution

Returns:

the convolved arrays f0*g0, f1*g1, etc.

static cross2D(a: numpy._typing.ArrayLike, b: numpy._typing.ArrayLike) ndarray

2D cross product

static cross3D(a: numpy._typing.ArrayLike, b: numpy._typing.ArrayLike) ndarray

3D cross product

rot2D(a: numpy._typing.ArrayLike) ndarray

2D rotational

rot3D(a: numpy._typing.ArrayLike) ndarray

3D rotational

rot3D_inv(a: numpy._typing.ArrayLike) ndarray

Inverse rotational for 3D fields, assuming div = 0

static inv(f: numpy._typing.ArrayLike) ndarray

Inverse of a linear operator.

it’s assumed that where the operator is zero, the function to invert will also be zero

div3D(a: numpy._typing.ArrayLike) ndarray

3D divergence

div2D(a: numpy._typing.ArrayLike) ndarray

2D divergence

inner_product(f: numpy._typing.ArrayLike, g: numpy._typing.ArrayLike) float

Log grid inner product

self_inner_product(f: numpy._typing.ArrayLike) float

inner product applied on oneself

P_projector(A: numpy._typing.ArrayLike) ndarray

Turns dUdt = A - gradP into dUdt = A'

Parameters:

AdUdt without the pressure term

Returns:

A'

enforce_grid_symmetry_arr(arr: numpy._typing.ArrayLike) ndarray

Force the f(-k)=f(k).conj symmetries along k=0 axes. Modifies the array in-place

enforce_grid_symmetry_dict(fields: dict) dict

forces symmetry for all fields of dict, in-place

class Physics(grid: Grid)

Computes a few classical physical properties

enstrophy() float

enstrophy Ω=ω²/2

energy() float

kinetic energy E=u²/2

helicity() complex

helicity H=u*ω

spectrum(fun: Callable[[dict[str, ndarray], ndarray], ndarray]) ndarray

Spectrum for the quantity calculated by the callback Callback takes two args: fields and ks. The first one is grid.fields. The second one is a grid-shaped bool array corresponding to concerned ks. The callback should return a summable np.ndarray [observable(k) for k in ks]. Ex kinetic energy 2D: fun(fields, ks) = ux[k]*conj(ux[k]) + uy[k]*conj(uy[k])

Returns:

np.ndarray of the spectrum along each point of grid.ks_1D

TODO update utest

cumulative_k(fun: Callable[[dict[str, ndarray], ndarray], ndarray]) ndarray

Compute the cumulative quantity between wave number 0 and k, defined by the sum over |k’| < k of that quantity TODO add utest

compute_by_shell(fun: Callable[[dict[str, ndarray], ndarray], ndarray], normalize: bool = False) ndarray

Structure function for the quantity calculated by the callback Callback takes two args: fields and ks. The first one is grid.fields. The second one is a grid-shaped bool array corresponding to concerned ks. The callback should return a summable np.ndarray [observable(k) for k in ks]. Ex kinetic energy 2D: fun(fields, ks) = ux[k]*conj(ux[k]) + uy[k]*conj(uy[k])

Parameters:
  • fun – the function to compute

  • normalize – if True, normalize the result on each shell

Returns:

np.ndarray of the structure function along each point of grid.ks_1D

TODO: add utest