Peano
Loading...
Searching...
No Matches
UpdateParticle_MultiLevelInteraction_Sets.py
Go to the documentation of this file.
1# This file is part of the Peano project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3from peano4.solversteps.ActionSet import ActionSet
4
5import jinja2
6
8
10
11
13 """!
14
15 Tree walker to realise particle-particle interactions which span multiple levels.
16
17 This code has the same semantics as peano4.toolbox.particles.UpdateParticle_MultiLevelInteraction_StackOfLists.
18 However, it uses a different container to maintain the active and local sets. Please consult the
19 documentation of UpdateParticle_MultiLevelInteraction_StackOfLists_ContiguousParticles for a description
20 of the arguments, plug-in points and the semantics of the two sets. Before you
21 do so, read throuth @ref page_toolbox_particles_mesh_traversal "the generic set discussion"
22 for the overall context.
23
24 As this class uses a ***set*** to maintain the active set and local set, the
25 tree walker works even if your particles change position and mesh level while
26 you traverse the mesh.
27
28
29 ## Realisation
30
31 Both the active set and the local set are realised as proper sets over
32 pointers. The sets are updated in touchCellFirstTime() and touchCellLastTime(),
33 i.e. when we walk down the tree or up again:
34
35 In touchCellFirstTime(), i.e. while we go from coarse to fine, we first
36 look at all the particles which are associated to an adjacent vertex of
37 the cell and are contained within the cell itself. These particles form
38 the local set.
39
40 Furthermore, we take the active set from coarser levels, and we add all
41 the particles which are associated with an adjacent vertex of the current
42 cell. If particles more from coarse to fine while we walk through the tree,
43 we encounter one out of two situations:
44 - If they are sieved within "our" current tree, we add them twice to the
45 active set. Once on the coarser level and then again on the finer one
46 into which they are sieved. For the present tree walker, this does not
47 matter, as we work with a set of pointers. The particle might be added
48 "too early", but it is not added multiple times to the active set.
49 - If they are sieved within another tree eventually, we might add it to
50 the active set even though they should be sieved down into another
51 branch of the tree. Should not make a difference.
52
53 In touchCellLastTime(), we take all the particles which are associated to
54 any adjacent vertex of the current cell, and we remove those particles
55 from the active set.
56
57
58 """
59
61 self,
62 particle_set,
63 particle_particle_interaction_kernel,
64 touch_vertex_first_time_compute_particle_update_kernel=None,
65 touch_vertex_last_time_compute_particle_update_kernel=None,
66 prepare_traversal_kernel="",
67 unprepare_traversal_kernel="",
68 additional_includes="",
69 active_particle_set=None,
70 ):
71 super(UpdateParticle_MultiLevelInteraction_Sets, self).__init__()
72 self._particle_set = particle_set
73 self.d = {}
74 self.d["LOCAL_PARTICLE"] = particle_set.particle_model.name
75 self.d["LOCAL_PARTICLES_CONTAINER"] = particle_set.name
76 if active_particle_set == None:
77 self.d["ACTIVE_PARTICLE"] = particle_set.particle_model.name
78 self.d["ACTIVE_PARTICLES_CONTAINER"] = particle_set.name
79 else:
80 self.d["ACTIVE_PARTICLE"] = active_particle_set.particle_model.name
81 self.d["ACTIVE_PARTICLES_CONTAINER"] = active_particle_set.name
82
83 self.d[
84 "PARTICLE_PARTICLE_INTERACTION_KERNEL"
85 ] = particle_particle_interaction_kernel
86 self.d[
87 "TOUCH_VERTEX_FIRST_COMPUTE_KERNEL"
88 ] = touch_vertex_first_time_compute_particle_update_kernel
89 self.d[
90 "TOUCH_VERTEX_LAST_COMPUTE_KERNEL"
91 ] = touch_vertex_last_time_compute_particle_update_kernel
92 self.d["PREPARE_TRAVERSAL_KERNEL"] = prepare_traversal_kernel
93 self.d["UNPREPARE_TRAVERSAL_KERNEL"] = unprepare_traversal_kernel
94
95 self.d["ADDITIONAL_INCLUDES"] = additional_includes
96
97 self.d["SET_IMPLEMENTATION"] = "std::unordered_set"
98
99 __Template_TouchVertexFirstTime = jinja2.Template(
100 """
101 {% if TOUCH_VERTEX_FIRST_COMPUTE_KERNEL!=None %}
102 auto& assignedParticles = fineGridVertex{{LOCAL_PARTICLES_CONTAINER}};
103 const int numberOfCoalescedAssignedParticles = -1;
104
105 {{TOUCH_VERTEX_FIRST_COMPUTE_KERNEL}}
106 {% endif %}
107"""
108 )
109
110 __Template_TouchVertexLastTime = jinja2.Template(
111 """
112 {% if TOUCH_VERTEX_LAST_COMPUTE_KERNEL!=None %}
113 auto& assignedParticles = fineGridVertex{{LOCAL_PARTICLES_CONTAINER}};
114 const int numberOfCoalescedAssignedParticles = -1;
115
116 {{TOUCH_VERTEX_LAST_COMPUTE_KERNEL}}
117 {% endif %}
118"""
119 )
120
121 __Template_TouchCellFirstTime = jinja2.Template(
122 """
123 {{SET_IMPLEMENTATION}}< globaldata::{{LOCAL_PARTICLE}}* > localParticles;
124 std::vector< int > numberOfCoalescedLocalParticlesPerVertex( TwoPowerD );
125 std::vector< int > _numberOfActiveParticlesPerVertex( TwoPowerD ); // stay compatible with coalesced version
126 auto& numberOfCoalescedActiveParticlesPerVertex = _numberOfActiveParticlesPerVertex;
127
128 for (int i=0; i<TwoPowerD; i++) {
129 numberOfCoalescedActiveParticlesPerVertex[i] = -1;
130 numberOfCoalescedLocalParticlesPerVertex[i] = -1;
131 for (auto* p: fineGridVertices{{ACTIVE_PARTICLES_CONTAINER}}(i) ) {
132 _activeParticles.insert( p );
133 }
134 for (auto* p: fineGridVertices{{LOCAL_PARTICLES_CONTAINER}}(i) ) {
135 localParticles.insert( p );
136 }
137 }
138
139 {% if PARTICLE_CELL_UPDATE_KERNEL!=None %}
140 {{SET_IMPLEMENTATION}}< globaldata::{{ACTIVE_PARTICLE}}* >& activeParticles = _activeParticles;
141 {{PARTICLE_PARTICLE_INTERACTION_KERNEL}}
142 {% endif %}
143"""
144 )
145
146 __Template_TouchCellLastTime = jinja2.Template(
147 """
148 for (int i=0; i<TwoPowerD; i++) {
149 for (auto* p: fineGridVertices{{ACTIVE_PARTICLES_CONTAINER}}(i) ) {
150 _activeParticles.erase( p );
151 }
152 }
153"""
154 )
155
156 def get_body_of_operation(self, operation_name):
157 result = "\n"
158 # if operation_name==ActionSet.OPERATION_BEGIN_TRAVERSAL:
159 # result = self.__Template_BeginTraversal.render(**self.d)
160 if operation_name == ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
161 result = self.__Template_TouchCellFirstTime.render(**self.d)
162 if operation_name == ActionSet.OPERATION_TOUCH_CELL_LAST_TIME:
163 result = self.__Template_TouchCellLastTime.render(**self.d)
164 if operation_name == ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME:
165 result = self.__Template_TouchVertexFirstTime.render(**self.d)
166 if operation_name == ActionSet.OPERATION_TOUCH_VERTEX_LAST_TIME:
167 result = self.__Template_TouchVertexLastTime.render(**self.d)
168 return result
169
171 return " return std::vector< peano4::grid::GridControlEvent >();\n"
172
174 return self.d["PREPARE_TRAVERSAL_KERNEL"]
175
177 return self.d["UNPREPARE_TRAVERSAL_KERNEL"]
178
180 return __name__.replace(".py", "").replace(".", "_")
181
183 return False
184
185 def get_includes(self):
186 result = jinja2.Template(
187 """
188#include "tarch/multicore/Lock.h"
189#include "toolbox/particles/particles.h"
190#include "vertexdata/{{LOCAL_PARTICLES_CONTAINER}}.h"
191#include "globaldata/{{LOCAL_PARTICLE}}.h"
192#include "vertexdata/{{ACTIVE_PARTICLES_CONTAINER}}.h"
193#include "globaldata/{{ACTIVE_PARTICLE}}.h"
194
195{{ADDITIONAL_INCLUDES}}
196
197#include <unordered_set>
198#include <set>
199#include <vector>
200"""
201 )
202 return result.render(**self.d)
203
204 def get_attributes(self):
205 result = jinja2.Template(
206 """
207 {{SET_IMPLEMENTATION}}< globaldata::{{ACTIVE_PARTICLE}}* > _activeParticles;
208 int _spacetreeId;
209"""
210 )
211 return result.render(**self.d)
212
214 return """
215 _spacetreeId = treeNumber;
216 """
Default superclass for any data model in Peano which is stored within the grid.
Definition DaStGen2.py:47
Action set (reactions to events)
Definition ActionSet.py:6
__init__(self, particle_set, particle_particle_interaction_kernel, touch_vertex_first_time_compute_particle_update_kernel=None, touch_vertex_last_time_compute_particle_update_kernel=None, prepare_traversal_kernel="", unprepare_traversal_kernel="", additional_includes="", active_particle_set=None)