-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspecies.h
498 lines (414 loc) · 12.5 KB
/
species.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
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
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
/**
* @file species.hpp
* @author your name ([email protected])
* @brief
* @version 0.1
* @date 2022-08-06
*
* @copyright Copyright (c) 2022
*
*/
#ifndef SPECIES_H_
#define SPECIES_H_
#include <string>
#include "zpic.h"
#include "particles.h"
#include "emf.h"
#include "current.h"
#include "density.h"
#include "moving_window.h"
#include "udist.h"
namespace phasespace {
enum quant { x, y, ux, uy, uz };
static inline void qinfo( quant q, std::string & name, std::string & label, std::string & units ) {
switch(q) {
case x :
name = "x"; label = "x"; units = "c/\\omega_n";
break;
case y :
name = "y"; label = "y"; units = "c/\\omega_n";
break;
case ux :
name = "ux"; label = "u_x"; units = "c";
break;
case uy :
name = "uy"; label = "u_y"; units = "c";
break;
case uz :
name = "uz"; label = "u_z"; units = "c";
break;
}
}
}
namespace species {
enum pusher { boris, euler };
namespace bc {
enum type { open = 0, periodic, reflecting };
}
typedef bnd<bc::type> bc_type;
}
/**
* @brief Charged particles class
*
*/
class Species {
protected:
/// @brief Associated sycl queue
sycl::queue * queue;
/// @brief Unique species identifier
int id;
/// @brief Nunber of particles per cell
uint2 ppc;
/// @brief reference particle charge
float q;
/// @brief Cell dize
float2 dx;
/// @brief Simulation box size
float2 box;
/// @brief Time step
float dt;
/// @brief Iteration
int iter;
/// @brief Particle data buffer
Particles *particles;
/// @brief Secondary data buffer to speed up some calculations
Particles *tmp;
/// @brief Particle tile sort aux. data
ParticleSort *sort;
/// @brief Initial density profile
Density::Profile * density;
/// @brief Number of particles being injected
int * np_inj;
/**
* @brief Process (physical) boundary conditions
*
*/
void process_bc();
private:
/// @brief Boundary condition
species::bc_type bc;
/// @brief Moving window information
MovingWindow moving_window;
/// @brief Initial velocity distribution
UDistribution::Type * udist;
/// @brief Total species energy on device
double * d_energy;
/// @brief Total number of particles moved
uint64_t * d_nmove;
/**
* @brief Shift particle positions due to moving window motion
*
*/
void move_window_shift();
/**
* @brief Inject new particles due to moving window motion
*
*/
void move_window_inject();
/**
* @brief Deposit 1D phasespace density
*
* @param d_data Data buffer
* @param q Quantity for axis
* @param range Value range
* @param size Number of grid points
*/
void dep_phasespace( float * const d_data,
phasespace::quant q, float2 const range, unsigned const size ) const;
/**
* @brief Deposit 2D phasespace density
*
* @param d_data Data buffer
* @param quant0 axis 0 quantity
* @param range0 axis 0 value range
* @param size0 axis 0 number of points
* @param quant1 axis 1 quantity
* @param range1 axis 1 value range
* @param size1 axis 1 number of points
*/
void dep_phasespace( float * const d_data,
phasespace::quant quant0, float2 range0, unsigned const size0,
phasespace::quant quant1, float2 range1, unsigned const size1 ) const;
public:
/// @brief Species name
const std::string name;
/// @brief Mass over charge ratio
const float m_q;
/// @brief Type of particle pusher to use
species::pusher push_type;
/**
* @brief Construct a new Species object
*
* @param name Name for the species object (used for diagnostics)
* @param m_q Mass over charge ratio
* @param ppc Number of particles per cell
*/
Species( std::string const name, float const m_q, uint2 const ppc );
/**
* @brief Initialize data structures
*
* @param box Simulation global box size
* @param ntiles Number of tiles
* @param nx Title grid dimension
* @param dt
* @param id
*/
virtual void initialize( float2 const box, uint2 const ntiles, uint2 const nx,
float const dt, int const id_, sycl::queue & queue );
/**
* @brief Destroy the Species object
*
*/
~Species();
/**
* @brief Set the density profile object
*
* @param new_density New density object to be cloned
*/
virtual void set_density( Density::Profile const & new_density ) {
delete density;
density = new_density.clone();
}
/**
* @brief Get the density object
*
* @return Density::Profile&
*/
Density::Profile & get_density() {
return * density;
}
/**
* @brief Set the velocity distribution object
*
* @param new_udist New udist object to be cloned
*/
virtual void set_udist( UDistribution::Type const & new_udist ) {
delete udist;
udist = new_udist.clone();
}
/**
* @brief Get the udist object
*
* @return UDistribution::Type&
*/
UDistribution::Type & get_udist() {
return *udist;
}
/**
* @brief Sets the boundary condition type
*
* @param new_bc
*/
void set_bc( species::bc_type new_bc ) {
// Validate parameters
if ( (new_bc.x.lower == species::bc::periodic) || (new_bc.x.upper == species::bc::periodic) ) {
if ( new_bc.x.lower != new_bc.x.upper ) {
std::cerr << "(*error*) Species boundary type mismatch along x.\n";
std::cerr << "(*error*) When choosing periodic boundaries both lower and upper types must be set to species::bc::periodic.\n";
exit(1);
}
}
if ( (new_bc.y.lower == species::bc::periodic) || (new_bc.y.upper == species::bc::periodic) ) {
if ( new_bc.y.lower != new_bc.y.upper ) {
std::cerr << "(*error*) Species boundary type mismatch along y.\n";
std::cerr << "(*error*) When choosing periodic boundaries both lower and upper types must be set to species::bc::periodic.\n";
exit(1);
}
}
// Store new values
bc = new_bc;
/*
std::string bc_name[] = {"open", "periodic", "reflecting"};
std::cout << "(*info*) Species " << name << " boundary conditions\n";
std::cout << "(*info*) x : [ " << bc_name[ bc.x.lower ] << ", " << bc_name[ bc.x.upper ] << " ]\n";
std::cout << "(*info*) y : [ " << bc_name[ bc.y.lower ] << ", " << bc_name[ bc.y.upper ] << " ]\n";
*/
// Set periodic flags on tile grids
if ( particles ) {
particles->periodic.x = ( bc.x.lower == species::bc::periodic );
particles->periodic.y = ( bc.y.lower == species::bc::periodic );
}
}
/**
* @brief Get the current boundary condition types
*
* @return species::bc_type
*/
species::bc_type get_bc( ) { return bc; }
/**
* @brief Sets moving window algorithm
*
* This method can only be called before the simulation has started (iter = 0)
*
* @return int 0 on success, -1 on error
*/
virtual int set_moving_window() {
if ( iter == 0 ) {
moving_window.init( dx.x );
bc.x.lower = bc.x.upper = species::bc::open;
particles->periodic.x = false;
return 0;
} else {
std::cerr << "(*error*) set_moving_window() called with iter != 0\n";
return -1;
}
}
/**
* @brief Inject particles in the simulation box
*
*/
virtual void inject();
/**
* @brief Inject particles in the specified range of the simulation
*
* @param range Range in which to inject particles
*/
virtual void inject( bnd<unsigned int> range );
/**
* @brief Gets number of particles that will be injected per tile
*
* @param range Range in which to inject particles
* @param np Device pointer to number of particles to be injected per tile
*/
virtual void np_inject( bnd<unsigned int> range, int * np );
/**
* @brief Advance particle velocities
*
* @param E Electric field
* @param B Magnetic field
*/
void push( vec3grid<float3> * const E, vec3grid<float3> * const B );
/**
* @brief Move particles (advance positions) and deposit current
*
* @param current Electric current density
*/
void move( vec3grid<float3> * const current );
/**
* @brief Move particles (advance positions), deposit current and shift positions
*
* @param current Electric current density
*/
void move( vec3grid<float3> * const current, int2 const shift );
/**
* @brief Move particles (advance positions) without depositing current
*
*/
void move( );
/**
* @brief Free stream particles 1 timestep
*
* Particles are free-streamed (no momentum update), no current is deposited.
* Used mostly for debug purposes.
*
*/
virtual void advance();
/**
* @brief Free stream particles 1 timestep
*
* Particles are free-streamed (no momentum update) and current is deposited
*
* @param current Electric current density
*/
virtual void advance( Current ¤t );
/**
* @brief Advance particles 1 timestep
*
* Momentum is advanced from EMF fields and current is deposited
*
* @param emf EM fields
* @param current Electric current density
*/
virtual void advance( EMF const &emf, Current ¤t );
/**
* @brief Advance particles 1 timestep and update moving window
*
* @param emf EM fields
* @param current Electric current density
*/
virtual void advance_mov_window( EMF const &emf, Current ¤t );
/**
* @brief Deposit species charge
*
* @param charge Charge density grid
*/
void deposit_charge( grid<float> &charge ) const;
/**
* @brief Returns total time centered kinetic energy
*
* @return double
*/
double get_energy() const {
double energy;
device::memcpy_tohost( &energy, d_energy, 1, *queue );
// Normalize enery value and return
return energy * q * m_q * dx.x * dx.y;
}
/**
* @brief Returns total number of particles moved
*
* @return uint64_t
*/
uint64_t get_nmove() const {
uint64_t nmove;
device::memcpy_tohost( &nmove, d_nmove, 1, *queue );
return nmove;
}
/**
* @brief Returns the maximum number of particles per tile
*
* @return auto
*/
uint32_t np_max_tile() const {
return particles -> np_max_tile();
}
/**
* @brief Returns the total number of particles
*
* @return auto
*/
uint64_t np_total() const {
return particles -> np_total();
}
/**
* @brief Save particle data to file
*
* Saves positions and velocities for all particles. Positions are currently
* normalized to cell size
*/
void save() const;
/**
* @brief Save charge density for species to file
*
*/
void save_charge() const;
/**
* @brief Save 1D phasespace density to file
*
* @param quant Phasespace quantity
* @param range Value range
* @param size Number of grid points
*/
void save_phasespace (
phasespace::quant quant, float2 const range, int const size ) const;
/**
* @brief Save 2D phasespace density to file
*
* @param quant0 axis 0 quantity
* @param range0 axis 0 value range
* @param size0 axis 0 number of points
* @param quant1 axis 1 quantity
* @param range1 axis 1 value range
* @param size1 axis 1 number of points
*/
void save_phasespace (
phasespace::quant quant0, float2 const range0, int const size0,
phasespace::quant quant1, float2 const range1, int const size1 ) const;
/**
* @brief Get the associated SYCL queue object
*
* @return sycl::queue&
*/
sycl::queue & get_queue( void ) { return *queue; }
};
#endif