99
1010
1111class Particle (object ):
12+ """
13+ Class to hold properties of a single particle.
14+
15+ Not sure need velocity (or mass?), but will store it
16+ here for now.
17+ """
1218
1319 def __init__ (self , x , y , u = 0 , v = 0 , mass = 1 ):
1420 self .x = x
@@ -41,7 +47,7 @@ def advect(self, u, v, dt):
4147
4248class Particles (object ):
4349
44- def __init__ (self , sim_data , bc , n_particles = 100 ):
50+ def __init__ (self , sim_data , bc , rp ):
4551 """
4652 Initialize the Particles object.
4753
@@ -53,11 +59,26 @@ def __init__(self, sim_data, bc, n_particles=100):
5359
5460 self .sim_data = sim_data
5561 self .bc = bc
62+ self .particles = set ()
63+ self .rp = rp
5664
5765 # TODO: read something from rp here to determine how to
5866 # generate the particles - for now, we shall assume random.
5967
60- self .randomly_generate_particles (n_particles )
68+ particle_generator = self .rp .get_param ("particles.particle_generator" )
69+ n_particles = self .rp .get_param ("particles.n_particles" )
70+ if n_particles <= 0 :
71+ msg .fail ("ERROR: n_particles = %s <= 0" % (n_particles ))
72+
73+ if particle_generator == "random" :
74+ self .randomly_generate_particles (n_particles )
75+ elif particle_generator == "grid" :
76+ self .grid_generate_particles (n_particles )
77+ else :
78+ msg .fail ("ERROR: do not recognise particle generator %s"
79+ % (particle_generator ))
80+
81+ self .n_particles = len (self .particles )
6182
6283 def randomly_generate_particles (self , n_particles ):
6384 """
@@ -75,6 +96,31 @@ def randomly_generate_particles(self, n_particles):
7596
7697 self .particles = set ([Particle (x , y ) for (x , y ) in positions ])
7798
99+ def grid_generate_particles (self , n_particles ):
100+ """
101+ Generate particles equally spaced across the grid.
102+
103+ If necessary, shall increase/decrease n_particles
104+ in order to
105+ """
106+ sq_n_particles = int (round (np .sqrt (n_particles )))
107+
108+ print (f'sq_n_particles = { sq_n_particles } ' )
109+
110+ if sq_n_particles ** 2 != n_particles :
111+ msg .warning ("WARNING: Changing number of particles from {} to {}" .format (n_particles , sq_n_particles ** 2 ))
112+
113+ myg = self .sim_data .grid
114+
115+ xs , step = np .linspace (myg .xmin , myg .xmax , num = sq_n_particles , endpoint = False , retstep = True )
116+ xs += 0.5 * step
117+ ys , step = np .linspace (myg .ymin , myg .ymax , num = sq_n_particles , endpoint = False , retstep = True )
118+ ys += 0.5 * step
119+
120+ print (f'xs = { xs } ' )
121+
122+ self .particles = set ([Particle (x , y ) for x in xs for y in ys ])
123+
78124 def update_particles (self , u , v , dt , limiter = 0 ):
79125 """
80126 Update the particles on the grid. To do this, we need to
@@ -89,7 +135,7 @@ def update_particles(self, u, v, dt, limiter=0):
89135 differently in different problems.
90136 """
91137 myg = self .sim_data .grid
92- myd = self .sim_data .data
138+ # myd = self.sim_data.data
93139
94140 # limit the velocity
95141
@@ -120,7 +166,7 @@ def update_particles(self, u, v, dt, limiter=0):
120166 if x_idx >= myg .nx :
121167 x_frac += (x_idx - myg .nx ) + 1
122168 x_idx = myg .nx - 1
123- if y_idx >= myg .ny :
169+ if y_idx >= myg .ny :
124170 y_frac += (y_idx - myg .ny ) + 1
125171 y_idx = myg .ny - 1
126172
@@ -167,47 +213,53 @@ def enforce_particle_boundaries(self):
167213 p = new_particles .pop ()
168214
169215 # -x boundary
170- if xlb == "outflow" :
171- if p . x < myg . xmin :
216+ if p . x < myg . xmin :
217+ if xlb in [ "outflow" , "neumann" ] :
172218 continue
173- elif xlb == "periodic" :
174- if p .x < myg .xmin :
219+ elif xlb == "periodic" :
175220 p .x = myg .xmax + p .x - myg .xmin
176- else :
177- msg .fail ("ERROR: xlb = %s invalid BC" % (xlb ))
221+ elif xlb in ["reflect-even" , "reflect-odd" ]:
222+ p .x = 2 * myg .xmin - p .x
223+ else :
224+ msg .fail ("ERROR: xlb = %s invalid BC" % (xlb ))
178225
179226 # +x boundary
180- if xrb == "outflow" :
181- if p . x > myg . xmax :
227+ if p . x > myg . xmax :
228+ if xrb in [ "outflow" , "neumann" ] :
182229 continue
183- elif xrb == "periodic" :
184- if p .x > myg .xmax :
230+ elif xrb == "periodic" :
185231 p .x = myg .xmin + p .x - myg .xmax
186- else :
187- msg .fail ("ERROR: xrb = %s invalid BC" % (xrb ))
232+ elif xrb in ["reflect-even" , "reflect-odd" ]:
233+ p .x = 2 * myg .xmax - p .x
234+ else :
235+ msg .fail ("ERROR: xrb = %s invalid BC" % (xrb ))
188236
189237 # -y boundary
190- if ylb == "outflow" :
191- if p . y < myg . ymin :
238+ if p . y < myg . ymin :
239+ if ylb in [ "outflow" , "neumann" ] :
192240 continue
193- elif ylb == "periodic" :
194- if p .y < myg .ymin :
241+ elif ylb == "periodic" :
195242 p .y = myg .ymax + p .y - myg .ymin
196- else :
197- msg .fail ("ERROR: ylb = %s invalid BC" % (ylb ))
198-
199- # +x boundary
200- if yrb == "outflow" :
201- if p .y > myg .ymax :
243+ elif ylb in ["reflect-even" , "reflect-odd" ]:
244+ p .y = 2 * myg .ymin - p .y
245+ else :
246+ msg .fail ("ERROR: ylb = %s invalid BC" % (ylb ))
247+
248+ # +y boundary
249+ if p .y > myg .ymax :
250+ if yrb in ["outflow" , "neumann" ]:
202251 continue
203- elif yrb == "periodic" :
204- if p .y > myg .ymax :
252+ elif yrb == "periodic" :
205253 p .y = myg .ymin + p .y - myg .ymax
206- else :
207- msg .fail ("ERROR: yrb = %s invalid BC" % (yrb ))
254+ elif yrb in ["reflect-even" , "reflect-odd" ]:
255+ p .y = 2 * myg .ymax - p .y
256+ else :
257+ msg .fail ("ERROR: yrb = %s invalid BC" % (yrb ))
208258
209259 self .particles .add (p )
210260
261+ self .n_particles = len (self .particles )
262+
211263 def get_positions (self ):
212264 """
213265 Return an array of particle positions.
0 commit comments