1- from ctypes import c_void_p
21from operator import attrgetter
32from typing import Literal
43
54import numpy as np
65
76from parcels .tools .statuscodes import StatusCode
87
9- __all__ = ["JITParticle" , "ScipyInteractionParticle" , "ScipyParticle" , "Variable" ]
10-
11- indicators_64bit = [np .float64 , np .uint64 , np .int64 , c_void_p ]
8+ __all__ = ["ScipyInteractionParticle" , "ScipyParticle" , "Variable" ]
129
1310
1411class Variable :
@@ -41,24 +38,14 @@ def name(self):
4138 def __get__ (self , instance , cls ):
4239 if instance is None :
4340 return self
44- if issubclass (cls , JITParticle ):
45- return instance ._cptr .__getitem__ (self .name )
46- else :
47- return getattr (instance , f"_{ self .name } " , self .initial )
41+ return getattr (instance , f"_{ self .name } " , self .initial )
4842
4943 def __set__ (self , instance , value ):
50- if isinstance (instance , JITParticle ):
51- instance ._cptr .__setitem__ (self .name , value )
52- else :
53- setattr (instance , f"_{ self .name } " , value )
44+ setattr (instance , f"_{ self .name } " , value )
5445
5546 def __repr__ (self ):
5647 return f"Variable(name={ self ._name } , dtype={ self .dtype } , initial={ self .initial } , to_write={ self .to_write } )"
5748
58- def is64bit (self ):
59- """Check whether variable is 64-bit."""
60- return True if self .dtype in indicators_64bit else False
61-
6249
6350class ParticleType :
6451 """Class encapsulating the type information for custom particles.
@@ -75,7 +62,7 @@ def __init__(self, pclass):
7562 if not issubclass (pclass , ScipyParticle ):
7663 raise TypeError ("Class object does not inherit from parcels.ScipyParticle" )
7764 self .name = pclass .__name__
78- self .uses_jit = issubclass ( pclass , JITParticle )
65+ self .uses_jit = False # TODO v4: remove this attribute
7966 # Pick Variable objects out of __dict__.
8067 self .variables = [v for v in pclass .__dict__ .values () if isinstance (v , Variable )]
8168 for cls in pclass .__bases__ :
@@ -92,8 +79,6 @@ def __init__(self, pclass):
9279 "Custom Variable name 'z' is not allowed, as it is used for depth in ParticleFile"
9380 )
9481 self .variables = ptype .variables + self .variables
95- # Sort variables with all the 64-bit first so that they are aligned for the JIT cptr
96- self .variables = [v for v in self .variables if v .is64bit ()] + [v for v in self .variables if not v .is64bit ()]
9782
9883 def __repr__ (self ):
9984 return f"{ type (self ).__name__ } (pclass={ self .name } )"
@@ -103,35 +88,6 @@ def __getitem__(self, item):
10388 if v .name == item :
10489 return v
10590
106- @property
107- def _cache_key (self ):
108- return "-" .join ([f"{ v .name } :{ v .dtype } " for v in self .variables ])
109-
110- @property
111- def dtype (self ):
112- """Numpy.dtype object that defines the C struct."""
113- type_list = [(v .name , v .dtype ) for v in self .variables ]
114- for v in self .variables :
115- if v .dtype not in self .supported_dtypes :
116- raise RuntimeError (str (v .dtype ) + " variables are not implemented in JIT mode" )
117- if self .size % 8 > 0 :
118- # Add padding to be 64-bit aligned
119- type_list += [("pad" , np .float32 )]
120- return np .dtype (type_list )
121-
122- @property
123- def size (self ):
124- """Size of the underlying particle struct in bytes."""
125- return sum ([8 if v .is64bit () else 4 for v in self .variables ])
126-
127- @property
128- def supported_dtypes (self ):
129- """List of all supported numpy dtypes. All others are not supported."""
130- # Developer note: other dtypes (mostly 2-byte ones) are not supported now
131- # because implementing and aligning them in cgen.GenerableStruct is a
132- # major headache. Perhaps in a later stage
133- return [np .int32 , np .uint32 , np .int64 , np .uint64 , np .float32 , np .double , np .float64 , c_void_p ]
134-
13591
13692class ScipyParticle :
13793 """Class encapsulating the basic attributes of a particle, to be executed in SciPy mode.
@@ -192,9 +148,7 @@ def __init__(self, lon, lat, pid, fieldset=None, ngrids=None, depth=0.0, time=0.
192148 initial = v .initial (self )
193149 else :
194150 initial = v .initial
195- # Enforce type of initial value
196- if v .dtype != c_void_p :
197- setattr (self , v .name , v .dtype (initial ))
151+ setattr (self , v .name , v .dtype (initial ))
198152
199153 def __del__ (self ):
200154 pass # superclass is 'object', and object itself has no destructor, hence 'pass'
@@ -267,7 +221,7 @@ def set_lonlatdepth_dtype(cls, dtype):
267221 cls .depth_nextloop .dtype = dtype
268222
269223 @classmethod
270- def setLastID (cls , offset ):
224+ def setLastID (cls , offset ): # TODO v4: check if we can implement this in another way
271225 ScipyParticle .lastID = offset
272226
273227
@@ -277,36 +231,5 @@ def setLastID(cls, offset):
277231
278232
279233class JITParticle (ScipyParticle ):
280- """Particle class for JIT-based (Just-In-Time) Particle objects.
281-
282- Parameters
283- ----------
284- lon : float
285- Initial longitude of particle
286- lat : float
287- Initial latitude of particle
288- fieldset : parcels.fieldset.FieldSet
289- mod:`parcels.fieldset.FieldSet` object to track this particle on
290- dt :
291- Execution timestep for this particle
292- time :
293- Current time of the particle
294-
295-
296- Notes
297- -----
298- Additional Variables can be added via the :Class Variable: objects
299-
300- Users should use JITParticles for faster advection computation.
301- """
302-
303234 def __init__ (self , * args , ** kwargs ):
304- self ._cptr = kwargs .pop ("cptr" , None )
305- if self ._cptr is None :
306- # Allocate data for a single particle
307- ptype = self .getPType ()
308- self ._cptr = np .empty (1 , dtype = ptype .dtype )[0 ]
309- super ().__init__ (* args , ** kwargs )
310-
311- def __del__ (self ):
312- super ().__del__ ()
235+ raise NotImplementedError ("JITParticle has been deprecated in Parcels v4. Use ScipyParticle instead." )
0 commit comments