simgeometry 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {simgeometry-0.1.0/src/simgeometry.egg-info → simgeometry-0.1.1}/PKG-INFO +1 -1
- {simgeometry-0.1.0 → simgeometry-0.1.1}/pyproject.toml +1 -1
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/domain_decomposition.py +217 -31
- {simgeometry-0.1.0 → simgeometry-0.1.1/src/simgeometry.egg-info}/PKG-INFO +1 -1
- {simgeometry-0.1.0 → simgeometry-0.1.1}/LICENSE.txt +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/README.md +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/setup.cfg +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/__init__.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/_bounds.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/_normalize.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/_particle_boundaries.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/_types.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/api.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/boundingbox.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/collection.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/crossings.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/cut_edges.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/cylindrical.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/evaluation.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/fractions.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/grid.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/__init__.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/_build.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/_metal.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/compile.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_ball/__init__.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_ball/contains_ball_cuda.cu +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_ball/contains_ball_metal.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_ball/contains_ball_numpy.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_ball/contains_ball_pyccel.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_box/__init__.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_box/contains_box_cuda.cu +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_box/contains_box_metal.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_box/contains_box_numpy.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_box/contains_box_pyccel.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_polygon_2d/__init__.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_polygon_2d/contains_polygon_2d_cuda.cu +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_polygon_2d/contains_polygon_2d_metal.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_polygon_2d/contains_polygon_2d_numpy.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_polygon_2d/contains_polygon_2d_pyccel.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/mesh.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/objects/__init__.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/objects/aperture2d.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/objects/aperture3d.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/objects/circle.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/objects/cuboid.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/objects/function_object.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/objects/line.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/objects/polygon.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/objects/polyline.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/objects/rectangle.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/objects/sphere.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/objects/triangle.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/operations.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/panels.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/plotting.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/py.typed +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/queries.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/sampling.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/shapes.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/simulation_domain.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/utils.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/visualization.py +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry.egg-info/SOURCES.txt +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry.egg-info/dependency_links.txt +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry.egg-info/requires.txt +0 -0
- {simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ requires = [ "setuptools", "wheel" ]
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "simgeometry"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.1"
|
|
8
8
|
description = "Shapes, grids, and simulation domains for numerical simulations"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
keywords = [ "geometry", "grids", "simulation", "mpi" ]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Process grid of the MPI ranks and the physical subdomain each one owns.
|
|
2
2
|
|
|
3
3
|
The process grid decides which rank owns which part of the domain. It is used for
|
|
4
|
-
particles (:meth:`DomainDecomposition.
|
|
4
|
+
particles (:meth:`DomainDecomposition.owner_ranks`) and, through
|
|
5
5
|
:meth:`DomainDecomposition.layout`, for the :class:`mpiarray.DistributedArray` of the
|
|
6
6
|
fields, so that markers and fields agree on who owns what.
|
|
7
7
|
"""
|
|
@@ -10,11 +10,82 @@ from __future__ import annotations
|
|
|
10
10
|
|
|
11
11
|
import math
|
|
12
12
|
from collections.abc import Sequence
|
|
13
|
+
from typing import Any, Literal, Protocol, runtime_checkable
|
|
13
14
|
|
|
15
|
+
import cunumpy as xp
|
|
14
16
|
import mpiarray as mpa
|
|
15
17
|
import numpy as np
|
|
16
18
|
from maybempi import MPI
|
|
17
19
|
|
|
20
|
+
Layout = Literal["component_major", "particle_major"]
|
|
21
|
+
"""Axis order of a positions array: ``(ndim, n)`` or ``(n, ndim)``."""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@runtime_checkable
|
|
25
|
+
class PositionDecomposition(Protocol):
|
|
26
|
+
"""What a particle container needs from a decomposition of physical space.
|
|
27
|
+
|
|
28
|
+
The bounds of the domain are already bound in, so a container only passes
|
|
29
|
+
positions. ``positions`` have shape ``(ndim, n)`` (component-major). This is
|
|
30
|
+
the structural interface of the object returned by
|
|
31
|
+
:meth:`DomainDecomposition.position_decomposition`; other decompositions
|
|
32
|
+
can implement it without importing simgeometry.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
comm: Any
|
|
36
|
+
rank: int
|
|
37
|
+
size: int
|
|
38
|
+
|
|
39
|
+
def owners(self, positions: Any) -> Any:
|
|
40
|
+
"""Return the rank owning each position, as an integer array of shape ``(n,)``."""
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
def owned_mask(self, positions: Any) -> Any:
|
|
44
|
+
"""Return a boolean array: which positions this rank owns."""
|
|
45
|
+
...
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class _BoundPositionDecomposition:
|
|
49
|
+
"""A :class:`DomainDecomposition` with the grid bounds bound in."""
|
|
50
|
+
|
|
51
|
+
def __init__(
|
|
52
|
+
self,
|
|
53
|
+
decomposition: DomainDecomposition,
|
|
54
|
+
lower_bound: tuple[float, ...],
|
|
55
|
+
upper_bound: tuple[float, ...],
|
|
56
|
+
num_gridpoints: tuple[int, ...],
|
|
57
|
+
) -> None:
|
|
58
|
+
decomposition._check_grid(lower_bound, upper_bound, num_gridpoints)
|
|
59
|
+
self._decomposition = decomposition
|
|
60
|
+
self._grid = (
|
|
61
|
+
tuple(float(v) for v in lower_bound),
|
|
62
|
+
tuple(float(v) for v in upper_bound),
|
|
63
|
+
tuple(int(v) for v in num_gridpoints),
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def comm(self) -> MPI.Comm | None:
|
|
68
|
+
"""Return the communicator of the decomposition."""
|
|
69
|
+
return self._decomposition.comm
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def rank(self) -> int:
|
|
73
|
+
"""Return this rank."""
|
|
74
|
+
return self._decomposition.mpi_rank
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def size(self) -> int:
|
|
78
|
+
"""Return the number of ranks."""
|
|
79
|
+
return self._decomposition.mpi_size
|
|
80
|
+
|
|
81
|
+
def owners(self, positions: Any, layout: Layout = "component_major") -> Any:
|
|
82
|
+
"""Return the owning rank of every position (see ``DomainDecomposition.owner_ranks``)."""
|
|
83
|
+
return self._decomposition.owner_ranks(positions, *self._grid, layout=layout)
|
|
84
|
+
|
|
85
|
+
def owned_mask(self, positions: Any, layout: Layout = "component_major") -> Any:
|
|
86
|
+
"""Return which positions this rank owns (see ``DomainDecomposition.owned_mask``)."""
|
|
87
|
+
return self._decomposition.owned_mask(positions, *self._grid, layout=layout)
|
|
88
|
+
|
|
18
89
|
|
|
19
90
|
class DomainDecomposition:
|
|
20
91
|
"""Represent the MPI process grid of a decomposed domain."""
|
|
@@ -307,8 +378,8 @@ class DomainDecomposition:
|
|
|
307
378
|
``num_nodes`` nodes of the axis (``n - 1`` cells over ``[lower,
|
|
308
379
|
upper]``, ``n`` on a periodic axis). Process coordinate ``c`` owns
|
|
309
380
|
``[edges[c], edges[c + 1])``, the cells whose lower node it owns; the
|
|
310
|
-
last one also owns ``upper
|
|
311
|
-
``
|
|
381
|
+
last one also owns ``upper`` and everything beyond, the first
|
|
382
|
+
everything below ``lower`` (see :meth:`owner_ranks`).
|
|
312
383
|
"""
|
|
313
384
|
num_procs = self.proc_sizes[dim]
|
|
314
385
|
if num_procs == 1 or self.replicated:
|
|
@@ -342,42 +413,157 @@ class DomainDecomposition:
|
|
|
342
413
|
upper.append(edges[proc_coord[dim] + 1])
|
|
343
414
|
return tuple(lower), tuple(upper)
|
|
344
415
|
|
|
345
|
-
def
|
|
416
|
+
def _check_grid(
|
|
346
417
|
self,
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
"""Return the rank owning a physical position in a decomposed grid."""
|
|
418
|
+
lower_bound: Sequence[float],
|
|
419
|
+
upper_bound: Sequence[float],
|
|
420
|
+
num_gridpoints: Sequence[int],
|
|
421
|
+
) -> None:
|
|
422
|
+
"""Raise if the grid description does not have ``ndim`` entries."""
|
|
353
423
|
if len(lower_bound) != self.ndim or len(upper_bound) != self.ndim:
|
|
354
424
|
raise ValueError("Bounds must match decomposition dimensions")
|
|
355
425
|
if len(num_gridpoints) != self.ndim:
|
|
356
426
|
raise ValueError("num_gridpoints must match decomposition dimensions")
|
|
357
427
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
428
|
+
def _components(self, positions: Any, layout: Layout) -> Any:
|
|
429
|
+
"""Return ``positions`` as a float ``(ndim, n)`` array on the active backend."""
|
|
430
|
+
if layout not in ("component_major", "particle_major"):
|
|
431
|
+
raise ValueError(
|
|
432
|
+
f"layout must be 'component_major' or 'particle_major', got {layout!r}"
|
|
433
|
+
)
|
|
434
|
+
positions = xp.asarray(positions, dtype=float)
|
|
435
|
+
if positions.ndim != 2:
|
|
436
|
+
raise ValueError(f"positions must be 2D, got shape {positions.shape}")
|
|
437
|
+
if layout == "particle_major":
|
|
438
|
+
positions = positions.T
|
|
439
|
+
if positions.shape[0] != self.ndim:
|
|
440
|
+
raise ValueError(
|
|
441
|
+
f"positions have {positions.shape[0]} components for layout "
|
|
442
|
+
f"{layout!r}, expected {self.ndim}"
|
|
443
|
+
)
|
|
444
|
+
return positions
|
|
445
|
+
|
|
446
|
+
def owner_ranks(
|
|
447
|
+
self,
|
|
448
|
+
positions: Any,
|
|
449
|
+
lower_bound: Sequence[float],
|
|
450
|
+
upper_bound: Sequence[float],
|
|
451
|
+
num_gridpoints: Sequence[int],
|
|
452
|
+
layout: Layout = "component_major",
|
|
453
|
+
) -> Any:
|
|
454
|
+
"""Return the rank owning each position, vectorised.
|
|
455
|
+
|
|
456
|
+
``positions`` is a NumPy or CuPy array (whatever the active cunumpy
|
|
457
|
+
backend is) of shape ``(ndim, n)`` for ``layout="component_major"``
|
|
458
|
+
(the default, the layout of the marker arrays) or ``(n, ndim)`` for
|
|
459
|
+
``layout="particle_major"``. The layout is never guessed, so ``n ==
|
|
460
|
+
ndim`` is not ambiguous. The result is an ``int64`` array of shape
|
|
461
|
+
``(n,)`` in the same memory as ``positions``; ranks are row-major over
|
|
462
|
+
:attr:`proc_sizes`.
|
|
463
|
+
|
|
464
|
+
Along each axis the subdomains are the blocks of
|
|
465
|
+
:meth:`subdomain_edges`: block ``c`` owns ``[edges[c], edges[c + 1])``.
|
|
466
|
+
**Out-of-range rule**: a position below the lower bound belongs to the
|
|
467
|
+
first block and one at or above the upper edge (including exactly the
|
|
468
|
+
upper bound) to the last block, that is, the block index is clipped into
|
|
469
|
+
``[0, proc_sizes - 1]`` per axis. A position outside the box is thus
|
|
470
|
+
owned by the nearest subdomain, so it is never shipped across the whole
|
|
471
|
+
domain and exactly one rank owns it; deciding what happens to it (kill,
|
|
472
|
+
reflect, wrap on a periodic axis) is the particle boundary condition's
|
|
473
|
+
job and must happen before the lookup. NaN positions go to the last
|
|
474
|
+
block. Without a decomposed axis every position belongs to rank 0.
|
|
475
|
+
"""
|
|
476
|
+
self._check_grid(lower_bound, upper_bound, num_gridpoints)
|
|
477
|
+
positions = self._components(positions, layout)
|
|
478
|
+
owners = xp.zeros(positions.shape[1], dtype=xp.int64)
|
|
479
|
+
for dim, num_procs in enumerate(self.proc_sizes):
|
|
480
|
+
if num_procs == 1 or self.replicated:
|
|
481
|
+
continue
|
|
368
482
|
edges = self.subdomain_edges(
|
|
369
|
-
dim,
|
|
483
|
+
dim,
|
|
484
|
+
float(lower_bound[dim]),
|
|
485
|
+
float(upper_bound[dim]),
|
|
486
|
+
int(num_gridpoints[dim]),
|
|
370
487
|
)
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
488
|
+
# The inner edges split the axis; searchsorted already yields
|
|
489
|
+
# 0 below the first and num_procs - 1 at or above the last.
|
|
490
|
+
coord = xp.searchsorted(
|
|
491
|
+
xp.asarray(edges[1:-1], dtype=float), positions[dim], side="right"
|
|
492
|
+
)
|
|
493
|
+
owners += coord * math.prod(self.proc_sizes[dim + 1 :])
|
|
494
|
+
return owners
|
|
495
|
+
|
|
496
|
+
def owned_mask(
|
|
497
|
+
self,
|
|
498
|
+
positions: Any,
|
|
499
|
+
lower_bound: Sequence[float],
|
|
500
|
+
upper_bound: Sequence[float],
|
|
501
|
+
num_gridpoints: Sequence[int],
|
|
502
|
+
layout: Layout = "component_major",
|
|
503
|
+
) -> Any:
|
|
504
|
+
"""Return which positions this rank owns, by the rule of :meth:`owner_ranks`.
|
|
505
|
+
|
|
506
|
+
Equal to ``owner_ranks(...) == mpi_rank`` (every rank owns everything
|
|
507
|
+
when no axis is decomposed), but only two comparisons per decomposed
|
|
508
|
+
axis against this rank's own edges, which is much cheaper than finding
|
|
509
|
+
every owner when most positions stay put.
|
|
510
|
+
"""
|
|
511
|
+
self._check_grid(lower_bound, upper_bound, num_gridpoints)
|
|
512
|
+
positions = self._components(positions, layout)
|
|
513
|
+
owned = xp.ones(positions.shape[1], dtype=bool)
|
|
514
|
+
coords = self.proc_coord
|
|
515
|
+
for dim, num_procs in enumerate(self.proc_sizes):
|
|
516
|
+
if num_procs == 1 or self.replicated:
|
|
517
|
+
continue
|
|
518
|
+
edges = self.subdomain_edges(
|
|
519
|
+
dim,
|
|
520
|
+
float(lower_bound[dim]),
|
|
521
|
+
float(upper_bound[dim]),
|
|
522
|
+
int(num_gridpoints[dim]),
|
|
523
|
+
)
|
|
524
|
+
coord = coords[dim]
|
|
525
|
+
column = positions[dim]
|
|
526
|
+
last = num_procs - 1
|
|
527
|
+
if coord > 0:
|
|
528
|
+
# ``~(<)`` rather than ``>=`` keeps NaN on the last block.
|
|
529
|
+
owned &= (
|
|
530
|
+
~(column < edges[coord])
|
|
531
|
+
if coord == last
|
|
532
|
+
else (column >= edges[coord])
|
|
533
|
+
)
|
|
534
|
+
if coord < last:
|
|
535
|
+
owned &= column < edges[coord + 1]
|
|
536
|
+
return owned
|
|
537
|
+
|
|
538
|
+
def owner_rank_for_position(
|
|
539
|
+
self,
|
|
540
|
+
position: Sequence[float] | np.ndarray,
|
|
541
|
+
lower_bound: tuple[float, ...],
|
|
542
|
+
upper_bound: tuple[float, ...],
|
|
543
|
+
num_gridpoints: tuple[int, ...],
|
|
544
|
+
) -> int:
|
|
545
|
+
"""Return the rank owning one physical position (see :meth:`owner_ranks`)."""
|
|
546
|
+
self._check_grid(lower_bound, upper_bound, num_gridpoints)
|
|
547
|
+
point = xp.asarray(position, dtype=float).reshape(-1, 1)
|
|
548
|
+
owners = self.owner_ranks(point, lower_bound, upper_bound, num_gridpoints)
|
|
549
|
+
return int(owners[0])
|
|
550
|
+
|
|
551
|
+
def position_decomposition(
|
|
552
|
+
self,
|
|
553
|
+
lower_bound: Sequence[float],
|
|
554
|
+
upper_bound: Sequence[float],
|
|
555
|
+
num_gridpoints: Sequence[int],
|
|
556
|
+
) -> PositionDecomposition:
|
|
557
|
+
"""Return this decomposition with the grid bounds bound in.
|
|
558
|
+
|
|
559
|
+
The result implements :class:`PositionDecomposition` (``comm``,
|
|
560
|
+
``rank``, ``size``, ``owners(positions)``, ``owned_mask(positions)``),
|
|
561
|
+
which is what a particle container needs; it does not change when the
|
|
562
|
+
bounds argument sequences are mutated afterwards.
|
|
563
|
+
"""
|
|
564
|
+
return _BoundPositionDecomposition(
|
|
565
|
+
self, tuple(lower_bound), tuple(upper_bound), tuple(num_gridpoints)
|
|
566
|
+
)
|
|
381
567
|
|
|
382
568
|
@property
|
|
383
569
|
def comm(self) -> MPI.Comm | None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_ball/contains_ball_cuda.cu
RENAMED
|
File without changes
|
{simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_ball/contains_ball_metal.py
RENAMED
|
File without changes
|
{simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_ball/contains_ball_numpy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_box/contains_box_cuda.cu
RENAMED
|
File without changes
|
{simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_box/contains_box_metal.py
RENAMED
|
File without changes
|
{simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_box/contains_box_numpy.py
RENAMED
|
File without changes
|
{simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_box/contains_box_pyccel.py
RENAMED
|
File without changes
|
{simgeometry-0.1.0 → simgeometry-0.1.1}/src/simgeometry/kernels/contains_polygon_2d/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|