parkipy.distributed.ewald.stokes_sl¶
- parkipy.distributed.ewald.stokes_sl(targets, sources, densities, options)¶
Compute the distributed Stokes single-layer potential.
\[\boldsymbol{u}(\boldsymbol{x}_i) = \sum_{j=1}^{N} \sum_{p \in P} \left( \frac{\boldsymbol{q}_j}{\lVert \boldsymbol{r}_{ij} \rVert} + \frac{\boldsymbol{r}_{ij} (\boldsymbol{r}_{ij} \cdot \boldsymbol{q}_j)} {\lVert \boldsymbol{r}_{ij} \rVert^3} \right),\]where \(\boldsymbol{r}_{ij} = \boldsymbol{x}_i - \boldsymbol{y}_j\) and \(P\) is the specified periodicity.
The computation is distributed across MPI ranks. Each rank provides its local slice of targets, sources, and densities. If
options.scatter == True(the default), particles are redistributed across ranks via an all-to-all before the Ewald sum; set it toFalseif the particles are already slab-distributed.Warning
Only
periodicity=1is currently supported.- Parameters:
targets (ndarray) – Local target positions \(\boldsymbol{x}_i\), shape
(3, nt_local)with default array ordering ('C'forcupy).sources (ndarray) – Local source positions \(\boldsymbol{y}_j\), shape
(3, ns_local)with default array ordering.densities (ndarray) – Single-layer density \(\boldsymbol{q}_j\) at each local source point, shape
(3, ns_local)with default array ordering.options (DistributedEwaldOptions) – Dataclass specifying Ewald and distributed execution parameters. See
DistributedEwaldOptions.
- Returns:
potential (ndarray) – Local Stokes single-layer potential at the (redistributed) target points, shape
(3, nt_local_out).targets (ndarray) – Redistributed target positions after the slab scatter, shape
(3, nt_local_out). Coordinates are in the global frame.walltime (dict, optional) – Per-stage wall-clock times (
'p2p','p2g','fft','cnv','ifft','g2p', and MPI communication stages). Only returned ifoptions.return_walltime == True.
- Raises:
NotImplementedError – If
options.periodicityis not1.
Notes
Parameter selection based off [1].
References
Examples
>>> from mpi4py import MPI >>> import parkipy >>> import numpy as np >>> mpi_comm = MPI.COMM_WORLD >>> size = mpi_comm.Get_size() >>> am = parkipy.utils.get_array_module( ... parkipy.utils.get_execution_space("Cuda") ... ) >>> box = [size, 1, 1] >>> ns = nt = 10000 >>> src = am.random.rand(3, ns) * am.array(box).reshape(3, 1) >>> trg = am.random.rand(3, nt) * am.array(box).reshape(3, 1) >>> dens = am.random.randn(3, ns) >>> options = parkipy.distributed.ewald.DistributedEwaldOptions( ... box=box, periodicity=1, tolerance=1e-4, ... execution_space="Cuda", cell_size=224, ... ) >>> pot, trg_out = parkipy.distributed.ewald.stokes_sl(trg, src, dens, options)