Skip to content

particula.particles.representation

representation

Particle representation for a collection of particles.

ParticleRepresentation

ParticleRepresentation(strategy: DistributionStrategy, activity: ActivityStrategy, surface: SurfaceStrategy, distribution: NDArray[float64], density: NDArray[float64], concentration: NDArray[float64], charge: NDArray[float64], volume: float = 1)

Everything needed to represent a particle or a collection of particles.

Represents a particle or a collection of particles, encapsulating the strategy for calculating mass, radius, and total mass based on a specified particle distribution, density, and concentration. This class allows for flexibility in representing particles.

Attributes:

  • - (strategy) –

    The computation strategy for particle representations.

  • - (activity) –

    The activity strategy for the partial pressure calculations.

  • - (surface) –

    The surface strategy for surface tension and Kelvin effect.

  • - (distribution) –

    The distribution data for the particles, which could represent sizes, masses, or another relevant metric.

  • - (density) –

    The density of the material from which the particles are made.

  • - (concentration) –

    The concentration of particles within the distribution.

  • - (charge) –

    The charge on each particle.

  • - (volume) –

    The air volume for simulation of particles in the air, default is 1 m^3. This is only used in ParticleResolved Strategies.

Methods: - get_strategy : Return the distribution strategy (optionally cloned). - get_strategy_name : Return the name of the distribution strategy. - get_activity : Return the activity strategy (optionally cloned). - get_activity_name : Return the name of the activity strategy. - get_surface : Return the surface strategy (optionally cloned). - get_surface_name : Return the name of the surface strategy. - get_distribution : Return the distribution array (optionally cloned). - get_density : Return the density array (optionally cloned). - get_concentration : Return the concentration array (optionally cloned). - get_total_concentration : Return the total concentration (1/m^3). - get_charge : Return the per-particle charge (optionally cloned). - get_volume : Return the representation volume in m^3 (optionally cloned). - get_species_mass : Return the mass per species, in kg. - get_mass : Return the array of total particle masses, in kg. - get_mass_concentration : Return the total mass concentration in kg/m^3. - get_radius : Return the array of particle radii in meters. - add_mass : Add mass to the distribution in each bin. - add_concentration : Add concentration to the distribution in each bin. - collide_pairs : Collide pairs of indices (ParticleResolved strategies).

Initialize the ParticleRepresentation.

Sets up the particle representation with required strategies and properties including distribution, density, concentration, charge, and volume for particle calculations.

Source code in particula/particles/representation.py
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
def __init__(
    self,
    strategy: DistributionStrategy,
    activity: ActivityStrategy,
    surface: SurfaceStrategy,
    distribution: NDArray[np.float64],
    density: NDArray[np.float64],
    concentration: NDArray[np.float64],
    charge: NDArray[np.float64],
    volume: float = 1,
):  # pylint: disable=too-many-positional-arguments, too-many-arguments
    """Initialize the ParticleRepresentation.

    Sets up the particle representation with required strategies and
    properties including distribution, density, concentration, charge,
    and volume for particle calculations.
    """
    self.strategy = strategy
    self.activity = activity
    self.surface = surface
    self.distribution = distribution
    self.density = density
    self.concentration = concentration
    self.charge = charge
    self.volume = volume

__str__

__str__() -> str

Returns a string representation of the particle representation.

Returns:

  • str
    • A string representation of the particle representation.
Example
Get String Representation
str_rep = str(particle_representation)
print(str_rep)
Source code in particula/particles/representation.py
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
def __str__(self) -> str:
    """Returns a string representation of the particle representation.

    Returns:
        - A string representation of the particle representation.

    Example:
        ``` py title="Get String Representation"
        str_rep = str(particle_representation)
        print(str_rep)
        ```
    """
    return (
        f"Particle Representation:\n"
        f"\tStrategy: {self.get_strategy_name()}\n"
        f"\tActivity: {self.get_activity_name()}\n"
        f"\tSurface: {self.get_surface_name()}\n"
        f"\tMass Concentration: "
        f"{self.get_mass_concentration():.3e} [kg/m^3]\n"
        f"\tNumber Concentration: "
        f"{self.get_total_concentration():.3e} [#/m^3]"
    )

add_concentration

add_concentration(added_concentration: NDArray[float64], added_distribution: Optional[NDArray[float64]] = None) -> None

Add concentration to the particle distribution.

Parameters:

  • - added_concentration

    The concentration to be added per bin (1/m^3).

  • - added_distribution

    Optional distribution array to merge into the existing distribution. If None, the current distribution is reused.

Example
Add Concentration
particle_representation.add_concentration(added_concentration)
Source code in particula/particles/representation.py
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
def add_concentration(
    self,
    added_concentration: NDArray[np.float64],
    added_distribution: Optional[NDArray[np.float64]] = None,
) -> None:
    """Add concentration to the particle distribution.

    Arguments:
        - added_concentration : The concentration to be added per bin
            (1/m^3).
        - added_distribution : Optional distribution array to merge into
          the existing distribution. If None, the current distribution
          is reused.

    Example:
        ``` py title="Add Concentration"
        particle_representation.add_concentration(added_concentration)
        ```
    """
    # if added_distribution is None, then it will be calculated
    if added_distribution is None:
        message = "Added distribution is value None."
        logger.warning(message)
        added_distribution = self.get_distribution()
    (self.distribution, self.concentration) = (
        self.strategy.add_concentration(
            distribution=self.get_distribution(),
            concentration=self.get_concentration(),
            added_distribution=added_distribution,
            added_concentration=added_concentration,
        )
    )
    self._enforce_increasing_bins()

add_mass

add_mass(added_mass: NDArray[float64]) -> None

Add mass to the particle distribution and update parameters.

Parameters:

  • - added_mass

    The mass to be added per distribution bin, in kg.

Example
Add Mass
particle_representation.add_mass(added_mass)
Source code in particula/particles/representation.py
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
def add_mass(self, added_mass: NDArray[np.float64]) -> None:
    """Add mass to the particle distribution and update parameters.

    Arguments:
        - added_mass : The mass to be added per distribution bin, in kg.

    Example:
        ``` py title="Add Mass"
        particle_representation.add_mass(added_mass)
        ```
    """
    (self.distribution, _) = self.strategy.add_mass(
        self.get_distribution(),
        self.get_concentration(),
        self.get_density(),
        added_mass,
    )
    self._enforce_increasing_bins()

collide_pairs

collide_pairs(indices: NDArray[int64]) -> None

Collide pairs of particles, used for ParticleResolved Strategies.

Performs coagulation between particle pairs by delegating to the distribution strategy's collide_pairs method. The smaller particle (first index in each pair) is merged into the larger particle (second index). Mass, concentration, and charge are all updated accordingly.

Charge conservation is handled automatically: if the particles have non-zero charges, they are summed during collisions. This enables physically accurate charge conservation in particle-resolved coagulation simulations.

Parameters:

  • - indices

    Array of particle pair indices to collide, shape (K, 2) where each row is [small_index, large_index].

Example
Collide Pairs
particle_representation.collide_pairs(indices)
Source code in particula/particles/representation.py
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
def collide_pairs(self, indices: NDArray[np.int64]) -> None:
    """Collide pairs of particles, used for ParticleResolved Strategies.

    Performs coagulation between particle pairs by delegating to the
    distribution strategy's collide_pairs method. The smaller particle
    (first index in each pair) is merged into the larger particle (second
    index). Mass, concentration, and charge are all updated accordingly.

    Charge conservation is handled automatically: if the particles have
    non-zero charges, they are summed during collisions. This enables
    physically accurate charge conservation in particle-resolved
    coagulation simulations.

    Arguments:
        - indices : Array of particle pair indices to collide, shape
            (K, 2) where each row is [small_index, large_index].

    Example:
        ``` py title="Collide Pairs"
        particle_representation.collide_pairs(indices)
        ```
    """
    (self.distribution, self.concentration, self.charge) = (  # type: ignore[assignment]
        self.strategy.collide_pairs(  # type: ignore[assignment]
            self.distribution,
            self.concentration,
            self.density,
            indices,
            self.charge,
        )
    )  # type: ignore[assignment]

get_activity

get_activity(clone: bool = False) -> ActivityStrategy

Return the activity strategy used for partial pressure calculations.

Parameters:

  • - clone

    If True, then return a deepcopy of the activity strategy.

Returns:

  • ActivityStrategy
    • The activity strategy used for partial pressure calculations.
Example
Get Activity Strategy
activity = particle_representation.get_activity()
Source code in particula/particles/representation.py
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
def get_activity(self, clone: bool = False) -> ActivityStrategy:
    """Return the activity strategy used for partial pressure calculations.

    Arguments:
        - clone : If True, then return a deepcopy of the activity strategy.

    Returns:
        - The activity strategy used for partial
          pressure calculations.

    Example:
        ``` py title="Get Activity Strategy"
        activity = particle_representation.get_activity()
        ```
    """
    if clone:
        return deepcopy(self.activity)
    return self.activity

get_activity_name

get_activity_name() -> str

Return the name of the activity strategy used for partial pressure calculations.

Returns:

  • str
    • The name of the activity strategy used for partial pressure calculations.
Example
Get Activity Strategy Name
activity_name = particle_representation.get_activity_name()
print(activity_name)
Source code in particula/particles/representation.py
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
def get_activity_name(self) -> str:
    """Return the name of the activity strategy used for partial pressure
    calculations.

    Returns:
        - The name of the activity strategy used for partial
          pressure calculations.

    Example:
        ``` py title="Get Activity Strategy Name"
        activity_name = particle_representation.get_activity_name()
        print(activity_name)
        ```
    """
    return self.activity.get_name()

get_charge

get_charge(clone: bool = False) -> NDArray[np.float64]

Return the charge per particle.

Parameters:

  • - clone

    If True, then return a copy of the charge array.

Returns:

  • NDArray[float64]
    • The charge of the particles (dimensionless).
Example
Get Charge Array
charge = particle_representation.get_charge()
Source code in particula/particles/representation.py
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
def get_charge(self, clone: bool = False) -> NDArray[np.float64]:
    """Return the charge per particle.

    Arguments:
        - clone : If True, then return a copy of the charge array.

    Returns:
        - The charge of the particles (dimensionless).

    Example:
        ``` py title="Get Charge Array"
        charge = particle_representation.get_charge()
        ```
    """
    if clone:
        return np.copy(self.charge)
    return self.charge

get_concentration

get_concentration(clone: bool = False) -> NDArray[np.float64]

Return the volume concentration of the particles.

For ParticleResolved Strategies, this is the number of particles per self.volume. Otherwise, it's per 1/m^3.

Parameters:

  • - clone

    If True, then return a copy of the concentration array.

Returns:

  • NDArray[float64]
    • The concentration of the particles in 1/m^3.
Example
Get Concentration Array
concentration = particle_representation.get_concentration()
Source code in particula/particles/representation.py
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
def get_concentration(self, clone: bool = False) -> NDArray[np.float64]:
    """Return the volume concentration of the particles.

    For ParticleResolved Strategies, this is the number of
    particles per self.volume. Otherwise, it's per 1/m^3.

    Arguments:
        - clone : If True, then return a copy of the concentration array.

    Returns:
        - The concentration of the particles in 1/m^3.

    Example:
        ``` py title="Get Concentration Array"
        concentration = particle_representation.get_concentration()
        ```
    """
    if clone:
        return np.copy(self.concentration / self.volume)
    return self.concentration / self.volume

get_density

get_density(clone: bool = False) -> NDArray[np.float64]

Return the density of the particles.

Parameters:

  • - clone

    If True, then return a copy of the density array.

Returns:

  • NDArray[float64]
    • The density of the particles.
Example
Get Density Array
density = particle_representation.get_density()
Source code in particula/particles/representation.py
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
def get_density(self, clone: bool = False) -> NDArray[np.float64]:
    """Return the density of the particles.

    Arguments:
        - clone : If True, then return a copy of the density array.

    Returns:
        - The density of the particles.

    Example:
        ``` py title="Get Density Array"
        density = particle_representation.get_density()
        ```
    """
    if clone:
        return np.copy(self.density)
    return self.density

get_distribution

get_distribution(clone: bool = False) -> NDArray[np.float64]

Return the distribution of the particles.

Parameters:

  • - clone

    If True, then return a copy of the distribution array.

Returns:

  • NDArray[float64]
    • The distribution of the particles.
Example
Get Distribution Array
distribution = particle_representation.get_distribution()
Source code in particula/particles/representation.py
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
def get_distribution(self, clone: bool = False) -> NDArray[np.float64]:
    """Return the distribution of the particles.

    Arguments:
        - clone : If True, then return a copy of the distribution array.

    Returns:
        - The distribution of the particles.

    Example:
        ``` py title="Get Distribution Array"
        distribution = particle_representation.get_distribution()
        ```
    """
    if clone:
        return np.copy(self.distribution)
    return self.distribution

get_effective_density

get_effective_density() -> NDArray[np.float64]

Return the effective density of the particles, weighted by the mass of the species.

Returns:

  • NDArray[float64]
    • The effective density of the particles.
Example
Get Effective Density Array
effective_density = particle_representation.get_effective_density()
Source code in particula/particles/representation.py
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
def get_effective_density(self) -> NDArray[np.float64]:
    """Return the effective density of the particles, weighted by the
    mass of the species.

    Arguments:
        - None

    Returns:
        - The effective density of the particles.

    Example:
        ``` py title="Get Effective Density Array"
        effective_density = particle_representation.get_effective_density()
        ```
    """
    densities = self.get_density()
    # if only one species is used, return the density of that species
    if isinstance(densities, float) or np.size(densities) == 1:
        return np.ones_like(self.get_species_mass()) * densities
    # calculate weighted particle density
    mass_total = self.get_mass()
    weighted_mass = np.sum(self.get_species_mass() * densities, axis=1)
    return np.divide(
        weighted_mass,
        mass_total,
        where=mass_total != 0,
        out=np.zeros_like(weighted_mass),
    )

get_mass

get_mass(clone: bool = False) -> NDArray[np.float64]

Return the mass of the particles as calculated by the strategy.

Parameters:

  • - clone

    If True, then return a copy of the mass array.

Returns:

  • NDArray[float64]
    • The mass of the particles in kg.
Example
Get Mass
mass = particle_representation.get_mass()
Source code in particula/particles/representation.py
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
def get_mass(self, clone: bool = False) -> NDArray[np.float64]:
    """Return the mass of the particles as calculated by the strategy.

    Arguments:
        - clone : If True, then return a copy of the mass array.

    Returns:
        - The mass of the particles in kg.

    Example:
        ``` py title="Get Mass"
        mass = particle_representation.get_mass()
        ```
    """
    if clone:
        return np.copy(
            self.strategy.get_mass(self.distribution, self.density)
        )
    return self.strategy.get_mass(self.distribution, self.density)

get_mass_concentration

get_mass_concentration(clone: bool = False) -> np.float64

Return the total mass per volume of the simulated particles.

The mass concentration is calculated from the distribution and concentration arrays.

Parameters:

  • - clone

    If True, then return a copy of the mass concentration value.

Returns:

  • float64
    • The mass concentration in kg/m^3.
Example
Get Mass Concentration
mass_concentration = (
    particle_representation.get_mass_concentration()
)
print(mass_concentration)
Source code in particula/particles/representation.py
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
def get_mass_concentration(self, clone: bool = False) -> np.float64:
    """Return the total mass per volume of the simulated particles.

    The mass concentration is calculated from the distribution
    and concentration arrays.

    Arguments:
        - clone : If True, then return a copy of the mass concentration
          value.

    Returns:
        - The mass concentration in kg/m^3.

    Example:
        ``` py title="Get Mass Concentration"
        mass_concentration = (
            particle_representation.get_mass_concentration()
        )
        print(mass_concentration)
        ```
    """
    if clone:
        return deepcopy(
            self.strategy.get_total_mass(
                self.get_distribution(),
                self.get_concentration(),
                self.get_density(),
            )
        )
    return self.strategy.get_total_mass(
        self.get_distribution(),
        self.get_concentration(),
        self.get_density(),
    )

get_mean_effective_density

get_mean_effective_density() -> float

Return the mean effective density of the particles.

Returns:

  • float
    • The mean effective density of the particles.
Example
Get Mean Effective Density Array
mean_effective_density = (
    particle_representation.get_mean_effective_density()
)
Source code in particula/particles/representation.py
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
def get_mean_effective_density(self) -> float:
    """Return the mean effective density of the particles.

    Arguments:
        - None

    Returns:
        - The mean effective density of the particles.

    Example:
        ``` py title="Get Mean Effective Density Array"
        mean_effective_density = (
            particle_representation.get_mean_effective_density()
        )
        ```
    """
    # filter out zero densities for no mass in bin/particle
    effective_density = self.get_effective_density()
    effective_density = effective_density[effective_density != 0]
    if effective_density.size == 0:
        return 0.0
    return np.mean(effective_density)

get_radius

get_radius(clone: bool = False) -> NDArray[np.float64]

Return the radius of the particles as calculated by the strategy.

Parameters:

  • - clone

    If True, then return a copy of the radius array.

Returns:

  • NDArray[float64]
    • The radius of the particles in meters.
Example
Get Radius
radius = particle_representation.get_radius()
Source code in particula/particles/representation.py
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
def get_radius(self, clone: bool = False) -> NDArray[np.float64]:
    """Return the radius of the particles as calculated by the strategy.

    Arguments:
        - clone : If True, then return a copy of the radius array.

    Returns:
        - The radius of the particles in meters.

    Example:
        ``` py title="Get Radius"
        radius = particle_representation.get_radius()
        ```
    """
    if clone:
        return np.copy(
            self.strategy.get_radius(self.distribution, self.density)
        )
    return self.strategy.get_radius(self.distribution, self.density)

get_species_mass

get_species_mass(clone: bool = False) -> NDArray[np.float64]

Return the masses per species in the particles.

Parameters:

  • - clone

    If True, then return a copy of the computed mass array.

Returns:

  • NDArray[float64]
    • The mass of the particles per species in kg.
Example
Get Species Mass
species_mass = particle_representation.get_species_mass()
Source code in particula/particles/representation.py
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
def get_species_mass(self, clone: bool = False) -> NDArray[np.float64]:
    """Return the masses per species in the particles.

    Arguments:
        - clone : If True, then return a copy of the computed mass array.

    Returns:
        - The mass of the particles per species in kg.

    Example:
        ``` py title="Get Species Mass"
        species_mass = particle_representation.get_species_mass()
        ```
    """
    if clone:
        return np.copy(
            self.strategy.get_species_mass(self.distribution, self.density)
        )
    return self.strategy.get_species_mass(self.distribution, self.density)

get_strategy

get_strategy(clone: bool = False) -> DistributionStrategy

Return the strategy used for particle representation.

Parameters:

  • - clone

    If True, then return a deepcopy of the strategy.

Returns:

Example
Get Strategy
strategy = particle_representation.get_strategy()
Source code in particula/particles/representation.py
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
def get_strategy(self, clone: bool = False) -> DistributionStrategy:
    """Return the strategy used for particle representation.

    Arguments:
        - clone : If True, then return a deepcopy of the strategy.

    Returns:
        - The strategy used for particle
            representation.

    Example:
        ``` py title="Get Strategy"
        strategy = particle_representation.get_strategy()
        ```
    """
    if clone:
        return deepcopy(self.strategy)
    return self.strategy

get_strategy_name

get_strategy_name() -> str

Return the name of the strategy used for particle representation.

Returns:

  • str
    • The name of the strategy used for particle representation.
Example
Get Strategy Name
strategy_name = particle_representation.get_strategy_name()
print(strategy_name)
Source code in particula/particles/representation.py
137
138
139
140
141
142
143
144
145
146
147
148
149
def get_strategy_name(self) -> str:
    """Return the name of the strategy used for particle representation.

    Returns:
        - The name of the strategy used for particle representation.

    Example:
        ``` py title="Get Strategy Name"
        strategy_name = particle_representation.get_strategy_name()
        print(strategy_name)
        ```
    """
    return self.strategy.get_name()

get_surface

get_surface(clone: bool = False) -> SurfaceStrategy

Return surface strategy for surface tension and Kelvin effect.

Parameters:

  • - clone

    If True, then return a deepcopy of the surface strategy.

Returns:

  • SurfaceStrategy
    • The surface strategy used for surface tension and Kelvin effect.
Example
Get Surface Strategy
surface = particle_representation.get_surface()
Source code in particula/particles/representation.py
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
def get_surface(self, clone: bool = False) -> SurfaceStrategy:
    """Return surface strategy for surface tension and Kelvin effect.

    Arguments:
        - clone : If True, then return a deepcopy of the surface strategy.

    Returns:
        - The surface strategy used for surface tension
          and Kelvin effect.

    Example:
        ``` py title="Get Surface Strategy"
        surface = particle_representation.get_surface()
        ```
    """
    if clone:
        return deepcopy(self.surface)
    return self.surface

get_surface_name

get_surface_name() -> str

Return the name of the surface strategy used for surface tension and Kelvin effect.

Returns:

  • str
    • The name of the surface strategy used for surface tension and Kelvin effect.
Example
Get Surface Strategy Name
surface_name = particle_representation.get_surface_name()
print(surface_name)
Source code in particula/particles/representation.py
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
def get_surface_name(self) -> str:
    """Return the name of the surface strategy used for surface tension and
    Kelvin effect.

    Returns:
        - The name of the surface strategy used for surface tension
          and Kelvin effect.

    Example:
        ``` py title="Get Surface Strategy Name"
        surface_name = particle_representation.get_surface_name()
        print(surface_name)
        ```
    """
    return self.surface.get_name()

get_total_concentration

get_total_concentration(clone: bool = False) -> np.float64

Return the total concentration of the particles.

Parameters:

  • - clone

    If True, then return a copy of the concentration array.

Returns:

  • float64
    • The total number concentration of the particles in 1/m^3.
Example
Get Total Concentration
total_concentration = (
    particle_representation.get_total_concentration()
)
print(total_concentration)
Source code in particula/particles/representation.py
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
def get_total_concentration(self, clone: bool = False) -> np.float64:
    """Return the total concentration of the particles.

    Arguments:
        - clone : If True, then return a copy of the concentration array.

    Returns:
        - The total number concentration of the particles in 1/m^3.

    Example:
        ``` py title="Get Total Concentration"
        total_concentration = (
            particle_representation.get_total_concentration()
        )
        print(total_concentration)
        ```
    """
    return np.sum(self.get_concentration(clone=clone))

get_volume

get_volume(clone: bool = False) -> float

Return the volume used for the particle representation.

Parameters:

  • - clone

    If True, then return a copy of the volume value.

Returns:

  • float
    • The volume of the particles in m^3.
Example
Get Volume
volume = particle_representation.get_volume()
Source code in particula/particles/representation.py
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
def get_volume(self, clone: bool = False) -> float:
    """Return the volume used for the particle representation.

    Arguments:
        - clone : If True, then return a copy of the volume value.

    Returns:
        - The volume of the particles in m^3.

    Example:
        ``` py title="Get Volume"
        volume = particle_representation.get_volume()
        ```
    """
    if clone:
        return deepcopy(self.volume)
    return self.volume