66License: BSD-3-Clause-LBNL
77"""
88
9- from .Iterator import next
9+ import warnings
10+
11+ from .Iterator import getitem , next
12+
13+
14+ def iterator (self , * args , level = None ):
15+ """Create an iterator over all particle tiles
16+
17+ Parameters
18+ ----------
19+ self : amrex.ParticleContainer_*
20+ A ParticleContainer class in pyAMReX
21+ args : deprecated positional argument
22+ level : int | str, optional
23+ The MR level. Allowed values are [0:finest_level+1) and "all".
24+ If there is more than one MR level, the argument is required.
25+
26+ Returns
27+ -------
28+ Iterator over all particle tiles at the specified level.
29+
30+ Examples
31+ --------
32+ >>> pc.iterator(level="all")
33+ >>> pc.iterator(level=0) # only particles on the the coarsest MR level
34+ """
35+ # Warn if a second positional argument is provided (ignored argument)
36+ if len (args ) > 0 :
37+ if len (args ) == 1 and isinstance (args [0 ], int ) and level is None :
38+ level = args [0 ]
39+ else :
40+ warnings .warn (
41+ "The second positional argument to iterator() is deprecated and ignored. "
42+ "Please update your code to use iterator(self, level=...) instead." ,
43+ DeprecationWarning ,
44+ stacklevel = 2 ,
45+ )
46+
47+ has_mr = self .finest_level > 0
48+
49+ if level is None :
50+ if has_mr :
51+ raise ValueError (
52+ "level must be specified for multi-level ParticleContainers"
53+ )
54+ else :
55+ level = 0
56+
57+ if level == "all" :
58+ raise ValueError ("level='all' is not yet supported for ParticleContainers" )
59+ # TODO: This does not work
60+ # for lvl in range(self.finest_level + 1):
61+ # yield self.Iterator(self, level=lvl)
62+ elif isinstance (level , int ) and level >= 0 :
63+ return self .Iterator (self , level = level )
64+ else :
65+ raise ValueError (
66+ f"level must be an integer in [0:finest_level+1) or 'all', but got: { level } "
67+ )
1068
1169
1270def pc_to_df (self , local = True , comm = None , root_rank = 0 ):
@@ -130,6 +188,7 @@ def register_ParticleContainer_extension(amr):
130188 ):
131189 ParIter_type .__next__ = next
132190 ParIter_type .__iter__ = lambda self : self
191+ ParIter_type .__getitem__ = getitem
133192
134193 # register member functions for every ParticleContainer_* type
135194 for _ , ParticleContainer_type in inspect .getmembers (
@@ -138,4 +197,8 @@ def register_ParticleContainer_extension(amr):
138197 and member .__module__ == amr .__name__
139198 and member .__name__ .startswith ("ParticleContainer_" ),
140199 ):
200+ ParticleContainer_type .iterator = iterator
201+ ParticleContainer_type .const_iterator = (
202+ iterator # TODO: simplified, code duplication
203+ )
141204 ParticleContainer_type .to_df = pc_to_df
0 commit comments