From 555f4351a0c53b2b36ebdce641d8f3c52c71c509 Mon Sep 17 00:00:00 2001 From: Thomas Marks Date: Fri, 10 Jan 2025 19:42:58 -0500 Subject: [PATCH] Python: useful error when `initialize_warpx` not called before creating `ParticleContainerWrapper` (#5412) Currently, WarpX is initialized when `sim.step` is called, or when the user calls `initialize_warpx`. However, if the user tries to create a `ParticleContainerWrapper` before this point, they get an error along the following lines: ``` File "/home/marksta/projects/warpx-ionization/picmi.py", line 185, in sim.run() File "/home/marksta/projects/warpx-ionization/picmi.py", line 179, in run self.elec_wrapper = particle_containers.ParticleContainerWrapper(self.electrons.name) File "/home/marksta/.local/lib/python3.10/site-packages/pywarpx/particle_containers.py", line 29, in __init__ mypc = libwarpx.warpx.multi_particle_container() File "/home/marksta/.local/lib/python3.10/site-packages/pywarpx/_libwarpx.py", line 46, in __getattr__ return self.__getattribute__(attribute) AttributeError: 'LibWarpX' object has no attribute 'warpx' ``` This is confusing. When I got this, I assumed I had maybe installed WarpX wrong. I added a catch for this exception that re-raises it with some additional context that should help direct the user to call `initialize_warpx` --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- Python/pywarpx/particle_containers.py | 30 +++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/Python/pywarpx/particle_containers.py b/Python/pywarpx/particle_containers.py index bc6b2d74106..db5dfda883e 100644 --- a/Python/pywarpx/particle_containers.py +++ b/Python/pywarpx/particle_containers.py @@ -24,10 +24,21 @@ class ParticleContainerWrapper(object): def __init__(self, species_name): self.name = species_name + self._particle_container = None + + @property + def particle_container(self): + if self._particle_container is None: + try: + mypc = libwarpx.warpx.multi_particle_container() + self._particle_container = mypc.get_particle_container_from_name( + self.name + ) + except AttributeError as e: + msg = "This is likely caused by attempting to access a ParticleContainerWrapper before initialize_warpx has been called" + raise AttributeError(msg) from e - # grab the desired particle container - mypc = libwarpx.warpx.multi_particle_container() - self.particle_container = mypc.get_particle_container_from_name(self.name) + return self._particle_container def add_particles( self, @@ -758,7 +769,18 @@ class ParticleBoundaryBufferWrapper(object): """ def __init__(self): - self.particle_buffer = libwarpx.warpx.get_particle_boundary_buffer() + self._particle_buffer = None + + @property + def particle_buffer(self): + if self._particle_buffer is None: + try: + self._particle_buffer = libwarpx.warpx.get_particle_boundary_buffer() + except AttributeError as e: + msg = "This is likely caused by attempting to access a ParticleBoundaryBufferWrapper before initialize_warpx has been called" + raise AttributeError(msg) from e + + return self._particle_buffer def get_particle_boundary_buffer_size(self, species_name, boundary, local=False): """