12 particle_cell_update_kernel=None,
13 touch_vertex_first_time_compute_particle_update_kernel=None,
14 touch_vertex_last_time_compute_particle_update_kernel=None,
15 prepare_traversal_kernel="",
16 unprepare_traversal_kernel="",
17 additional_includes="",
18 active_particle_set=None,
22 Update particles on a single level
24 To be used if you want to update particles within their cell, while they
27 - do not interact at all; or
28 - interact only with particles on the same mesh level.
30 This code snippet creates a tree walker, i.e. an action set that runs
31 through the underlying spacetree top-down. Users can plug into what
32 happens per cell and what happens when we touch a set of particles for
33 the first and for the last time.
37 Per tree node (cell) there are two different sets.
38 The set of local particles of a cell are all of the particles whose
39 centre is contained within the cell.
40 The set of active particles are all particles which are associated
41 with an adjacent vertex of the cell.
42 In line with @ref page_toolbox_particles_mesh_storage "Peano's particle storage scheme",
43 this effectively means that the active particles are those from the
44 cell plus its h/2 environment.
46 If the active_particle_set attribute is None, then
47 the active set and the local set are of the same type. They are
48 however not the same sets, as one contains only the particles held
50 You can set the active set to another species of particles
51 and thus couple two types of particles.
53 The local set is a strict subset of the active set per cell. The code has
54 not checked beforehand if its particles overlap with the current cell.
59 Besides the cell kernel which is there to realise per-cell updates,
60 we also have a vertex kernel which we call whenever a
61 vertex is loaded for the first time. That is, you can assume that the
62 vertex kernel has been launched for all 2^d vertices of a cell before
63 its cell kernel is triggered. The vertex kernel has access to a local
64 set: These sets contain all the particles
65 whose centre lies within the square/cube around the vertex with mesh size
66 2h. So this area goes h along each each coordinate axis into the
67 neighbouring cells. The vertex's local particles also have to reside
68 on the same resolution level.
73 - You can use this action set to realise particle updates without any
74 dependencies on other particles.
75 - You can use this action set to realise particle updates where the
76 particle depends on other particles which are stored on the same
79 The following constraints apply:
81 - If you work with the local set within the cell, you are on the safe
82 side, though the association of particles to cells is not unique.
83 There is a tiny overlap between cells, i.e. particles on the face
84 between two cells might be associated to both cells. If you update
85 particles, you should employ a boolean flag to memorise if a particle
86 has been updated already or not.
87 - If you work with the local set within a vertex, this local set overlaps
88 with adjacent cells (see previous item), and it might even overlap with
90 - If you change a particle position while the action set runs, you might
91 end up with inconsistent data view.
94 ## Validity if particles change their position of cut-off radius
96 This particular action set constructs its active and local sets totally
97 on-the-fly. It does not maintain any data while is marches through the
98 mesh. Consequently, it is robust w.r.t. particle position updates or
99 lift and drops and in general any resorting.
104 @param particle_set: ParticleSet
106 @param particle_particle_interaction_kernel: String holding C++ code
107 This C++ code can access three different types of variables: There's
108 a list of particles called activeParticles, there's a list of particles
109 called localParticles, and there's the cell marker. See the guidebook
110 for further info. A typical kernel resembles
112 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
113 for (auto* localParticle: localParticles )
114 for (auto* activeParticle: activeParticles ) {
115 localParticle->doSomethingFancy( activeParticle );
117 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119 @param active_particle_set: ParticleSet or None
120 You can compare different particles species with this argument. It
121 allows you to make the active particles stem from another species than
122 the local ones that you actually update. Pick None if both sets are of
125 @param touch_vertex_first_time_compute_particle_update_kernel: String or None
126 Can be empty, but if you wanna move particles, then a minimal example
129 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
130 for (auto* localParticle: localParticles ) {
131 localParticle->setMoveState( globaldata::Particle::MoveState::NotMovedYet );
133 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
135 i.e. you will have a variable localParticle available in this kernel
136 and it is a pointer. There is no notion of an active variable for
137 touch first or touch last.
141 super(UpdateParticle_SingleLevelInteraction, self).
__init__(
142 descend_invocation_order=1, parallel=
False
147 self.
d[
"LOCAL_PARTICLE"] = particle_set.particle_model.name
148 self.
d[
"LOCAL_PARTICLES_CONTAINER"] = particle_set.name
149 if active_particle_set ==
None:
150 self.
d[
"ACTIVE_PARTICLE"] = particle_set.particle_model.name
151 self.
d[
"ACTIVE_PARTICLES_CONTAINER"] = particle_set.name
153 self.
d[
"ACTIVE_PARTICLE"] = active_particle_set.particle_model.name
154 self.
d[
"ACTIVE_PARTICLES_CONTAINER"] = active_particle_set.name
155 self.
d[
"PARTICLE_CELL_UPDATE_KERNEL"] = particle_cell_update_kernel
157 "TOUCH_VERTEX_FIRST_COMPUTE_KERNEL"
158 ] = touch_vertex_first_time_compute_particle_update_kernel
160 "TOUCH_VERTEX_LAST_COMPUTE_KERNEL"
161 ] = touch_vertex_last_time_compute_particle_update_kernel
162 self.
d[
"ADDITIONAL_INCLUDES"] = additional_includes
163 self.
d[
"PREPARE_TRAVERSAL_KERNEL"] = prepare_traversal_kernel
164 self.
d[
"UNPREPARE_TRAVERSAL_KERNEL"] = unprepare_traversal_kernel