Skip to content

Commit 84973ef

Browse files
authored
Merge pull request #8 from budjensen/fix/code-formatting
docs: add module and function docstrings for particles.py and test_sp…
2 parents 94d6436 + 373fa70 commit 84973ef

File tree

2 files changed

+162
-34
lines changed

2 files changed

+162
-34
lines changed

src/test_particle_sim_1d/particles.py

Lines changed: 128 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,37 @@
11
"""
22
particles.py
33
4-
Defines the Species class: a Structure-of-Arrays (SoA) container that stores
5-
properties of particles belonging to one species (e.g., electrons or ions).
64
5+
Defines the ``Species`` class: a Structure-of-Arrays (SoA) container that stores
6+
properties of particles belonging to one species (e.g., electrons or ions) in a
7+
1D-in-space, 3D-in-velocity (1D3V) plasma simulation.
8+
9+
10+
The class keeps positions, velocity components, weights, and alive flags in
11+
separate NumPy arrays for efficient vectorized operations.
12+
13+
14+
Classes
15+
-------
16+
Species
17+
Container for one particle species (e.g., electrons, ions).
18+
19+
20+
Examples
21+
--------
22+
Create an electron species and populate it with uniformly distributed particles:
23+
24+
25+
>>> import numpy as np
26+
>>> from test_particle_sim_1d.particles import Species
27+
>>> electrons = Species(q=-1.0, m=1.0, name="electron", capacity=100)
28+
>>> electrons.initialize_uniform(n=10, z_min=-0.1, z_max=0.1, v0=0.0, seed=42)
29+
>>> len(electrons)
30+
10
31+
>>> electrons.z.shape
32+
(100,)
733
"""
834

9-
# import statements
1035
from __future__ import annotations
1136

1237
import numpy as np
@@ -15,10 +40,13 @@
1540
# species class definition
1641
class Species:
1742
"""
18-
A simple Structure-of-Arrays (SoA) representation of a particle species.
43+
Structure-of-Arrays (SoA) container for a single particle species.
44+
45+
46+
Each physical quantity (position, velocity components, etc.) is stored in
47+
its own contiguous NumPy array for efficient vectorized operations in a
48+
1D-in-space, 3D-in-velocity (1D3V) simulation.
1949
20-
Each physical quantity (position, velocity, etc.) is stored in its own
21-
contiguous NumPy array for efficient vectorized operations.
2250
2351
Attributes
2452
----------
@@ -51,7 +79,29 @@ def __init__(
5179
capacity: int = 0,
5280
dtype=np.float64,
5381
) -> None:
54-
"""Initialize empty species container"""
82+
"""
83+
Initialize an empty species container.
84+
85+
86+
Parameters
87+
----------
88+
q : float
89+
Charge of one particle in Coulombs.
90+
m : float
91+
Mass of one particle in kilograms.
92+
name : str, optional
93+
Label for this species, e.g., "electron" or "ion".
94+
capacity : int, optional
95+
Initial capacity (number of particle slots) to allocate.
96+
dtype : numpy.dtype, optional
97+
Floating-point dtype used for internal arrays (default numpy.float64).
98+
99+
100+
Returns
101+
-------
102+
None
103+
"""
104+
55105
# store physical constants and identifiers
56106
self.q = float(q) # float
57107
self.m = float(m) # float
@@ -74,19 +124,27 @@ def __init__(
74124
# public methods
75125
def add_particles(self, z_init: np.ndarray, v_init: np.ndarray) -> None:
76126
"""
77-
Append new particles to this species
127+
Append new particles to this species.
128+
78129
79130
Parameters
80131
----------
81132
z_init : np.ndarray
82-
Initial positions of new particles
83-
vx_init : np.ndarray
84-
Initial velocities of new particles
133+
Initial positions of new particles, shape ``(N,)``.
134+
v_init : np.ndarray
135+
Initial velocities of new particles, shape ``(N, 3)``, ordered
136+
as ``(vx, vy, vz)``.
137+
138+
139+
Returns
140+
-------
141+
None
142+
85143
86144
Notes
87145
-----
88-
function assumes both arrays are the same length
89-
arrays are appended to the end of the current data
146+
The two input arrays must have the same leading dimension ``N``.
147+
New particles are appended to the end of the existing data.
90148
"""
91149

92150
# number of new particles being added
@@ -122,18 +180,28 @@ def initialize_uniform(
122180
seed: int | None = None,
123181
) -> None:
124182
"""
125-
Create N particles uniformly distributed in space
183+
Create particles uniformly distributed in space.
184+
126185
127186
Parameters
128187
----------
129188
n : int
130-
number of particles to create
131-
x_min, x_max : float
132-
spatial bounds for uniform distribution
133-
v0 : float, optional
134-
initial velocity assigned to all particles (default 0)
189+
Number of particles to create.
190+
z_min : float
191+
Lower bound of the position domain.
192+
z_max : float
193+
Upper bound of the position domain.
194+
v0 : float or array_like, optional
195+
Initial velocity assigned to all particles. If scalar, it is
196+
interpreted as a single component value; if array-like, it should
197+
broadcast to shape ``(3,)``. Default is 0.0.
135198
seed : int or None, optional
136-
random seed for reproducibility
199+
Random seed for reproducibility.
200+
201+
202+
Returns
203+
-------
204+
None
137205
"""
138206
# initialize random number generator (NumPy's modern API)
139207
rng = np.random.default_rng(seed)
@@ -142,20 +210,41 @@ def initialize_uniform(
142210
z_new = rng.uniform(z_min, z_max, size=n).astype(self.dtype)
143211

144212
# all velocities start with the same value v0
145-
if v0 is None:
146-
v_new = np.zeros((n, 3), dtype=self.dtype)
147-
else:
148-
v_new = np.tile(v0, (n, 1))
213+
v_new = (
214+
np.zeros((n, 3), dtype=self.dtype) if v0 is None else np.tile(v0, (n, 1))
215+
)
149216

150217
# reuse add_particles to avoid repeating logic (DRY principle)
151218
self.add_particles(z_new, v_new)
152219

153220
def __len__(self) -> int:
221+
"""
222+
Number of particles currently stored in this species.
223+
224+
225+
Returns
226+
-------
227+
int
228+
The number of particles ``N``.
229+
"""
154230
return self.N
155231

156232
# internal helpers
157233
def _ensure_capacity(self, needed: int) -> None:
158-
"""Expand storage arrays if needed"""
234+
"""
235+
Ensure that internal arrays can hold at least ``needed`` particles.
236+
237+
238+
Parameters
239+
----------
240+
needed : int
241+
Required number of particle slots.
242+
243+
244+
Returns
245+
-------
246+
None
247+
"""
159248

160249
# guard pattern: early return if no expansion needed
161250
if needed <= self.capacity:
@@ -183,24 +272,30 @@ def _grow(
183272
array_dtype=None,
184273
) -> np.ndarray:
185274
"""
186-
Create a larger copy of existing array
275+
Create a larger copy of an existing 1D array.
276+
187277
188278
Parameters
189279
----------
190280
arr : np.ndarray
191-
old array to copy from
281+
Original array to copy from.
192282
new_cap : int
193-
desired total length
194-
fill : scalar
195-
value to fill the new (empty) portion with
196-
array_dtype : np.dtype or None
197-
optionally override dtype (used for bool arrays)
283+
Desired total length of the returned array.
284+
fill : scalar, optional
285+
Value used to initialize the newly allocated portion
286+
(elements from ``len(arr)`` to ``new_cap - 1``).
287+
array_dtype : numpy.dtype or None, optional
288+
Optional dtype override for the returned array. If None,
289+
``arr.dtype`` is used.
290+
198291
199292
Returns
200293
-------
201294
np.ndarray
202-
new array containing the old data plus new filler elements
295+
New array of length ``new_cap`` containing the original data in
296+
the first ``len(arr)`` entries and the ``fill`` value in the rest.
203297
"""
298+
204299
# pick the right data type
205300
dtype = array_dtype or arr.dtype
206301

tests/test_species1.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,37 @@
1-
# tests/test_species.py
1+
"""
2+
tests/test_species1.py
3+
4+
5+
Unit tests for the Species class defined in ``test_particle_sim_1d/particles.py``.
6+
7+
8+
These tests verify correct initialization, particle addition, and array
9+
management behavior for the Species container, which stores particle
10+
positions, velocities, and related attributes in a Structure-of-Arrays (SoA)
11+
layout for 1D-in-space, 3D-in-velocity (1D3V) plasma simulations.
12+
13+
14+
Functions
15+
---------
16+
test_species_initialization :
17+
Ensure that a Species object can be created and initialized correctly.
18+
test_add_particles_increases_count :
19+
Verify that adding new particles updates internal arrays and counts as expected.
20+
21+
22+
Examples
23+
--------
24+
>>> from test_particle_sim_1d.particles import Species
25+
>>> import numpy as np
26+
>>> s = Species(q=-1.602e-19, m=9.109e-31, name="electron", capacity=10)
27+
>>> s.initialize_uniform(n=3, z_min=-0.1, z_max=0.1, v0=0.0)
28+
>>> len(s)
29+
3
30+
>>> s.add_particles(np.array([0.2]), np.array([[0.0, 0.0, 1.0]]))
31+
>>> len(s)
32+
4
33+
"""
34+
235
from __future__ import annotations
336

437
import numpy as np

0 commit comments

Comments
 (0)