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 std::vector< bool > localParticleIsContainedInCell;
127 auto& numberOfCoalescedActiveParticlesPerVertex = _numberOfActiveParticlesPerVertex;
128
129 for (int i=0; i<TwoPowerD; i++) {
130 numberOfCoalescedActiveParticlesPerVertex[i] = -1;
131 numberOfCoalescedLocalParticlesPerVertex[i] = -1;
132 for (auto* p: fineGridVertices{{ACTIVE_PARTICLES_CONTAINER}}(i) ) {
133 _activeParticles.insert( p );
134 }
135 for (auto* p: fineGridVertices{{LOCAL_PARTICLES_CONTAINER}}(i) ) {
136 std::bitset<TwoPowerD> mask = 0;
137 mask.set(TwoPowerD-i-1);
138 bool isLocal = (mask & p->getContainedInAdjacentCell()).any();
139 assertionEquals4(
140 isLocal,
141 marker.isContained( p->getX(), toolbox::particles::internal::relativeGrabOwnershipSpatialSortingTolerance( marker.h() ) * tarch::la::NUMERICAL_ZERO_DIFFERENCE ),
142 marker.toString(), p->toString(), i, mask
143 );
144 localParticleIsContainedInCell.push_back( isLocal );
145 localParticles.insert( p );
146 }
147 }
148
149 {% if PARTICLE_CELL_UPDATE_KERNEL!=None %}
150 {{SET_IMPLEMENTATION}}< globaldata::{{ACTIVE_PARTICLE}}* >& activeParticles = _activeParticles;
151 {{PARTICLE_PARTICLE_INTERACTION_KERNEL}}
152 {% endif %}
153"""
154 )
155
156 __Template_TouchCellLastTime = jinja2.Template(
157 """
158 for (int i=0; i<TwoPowerD; i++) {
159 for (auto* p: fineGridVertices{{ACTIVE_PARTICLES_CONTAINER}}(i) ) {
160 _activeParticles.erase( p );
161 }
162 }
163"""
164 )
165
166 def get_body_of_operation(self, operation_name):
167 result = "\n"
168 # if operation_name==ActionSet.OPERATION_BEGIN_TRAVERSAL:
169 # result = self.__Template_BeginTraversal.render(**self.d)
170 if operation_name == ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
171 result = self.__Template_TouchCellFirstTime.render(**self.d)
172 if operation_name == ActionSet.OPERATION_TOUCH_CELL_LAST_TIME:
173 result = self.__Template_TouchCellLastTime.render(**self.d)
174 if operation_name == ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME:
175 result = self.__Template_TouchVertexFirstTime.render(**self.d)
176 if operation_name == ActionSet.OPERATION_TOUCH_VERTEX_LAST_TIME:
177 result = self.__Template_TouchVertexLastTime.render(**self.d)
178 return result
179
181 return " return std::vector< peano4::grid::GridControlEvent >();\n"
182
184 return self.d["PREPARE_TRAVERSAL_KERNEL"]
185
187 return self.d["UNPREPARE_TRAVERSAL_KERNEL"]
188
190 return __name__.replace(".py", "").replace(".", "_")
191
193 return False
194
195 def get_includes(self):
196 result = jinja2.Template(
197 """
198#include "tarch/multicore/Lock.h"
199#include "toolbox/particles/particles.h"
200#include "vertexdata/{{LOCAL_PARTICLES_CONTAINER}}.h"
201#include "globaldata/{{LOCAL_PARTICLE}}.h"
202#include "vertexdata/{{ACTIVE_PARTICLES_CONTAINER}}.h"
203#include "globaldata/{{ACTIVE_PARTICLE}}.h"
204
205{{ADDITIONAL_INCLUDES}}
206
207#include <unordered_set>
208#include <set>
209#include <vector>
210"""
211 )
212 return result.render(**self.d)
213
214 def get_attributes(self):
215 result = jinja2.Template(
216 """
217 {{SET_IMPLEMENTATION}}< globaldata::{{ACTIVE_PARTICLE}}* > _activeParticles;
218 int _spacetreeId;
219"""
220 )
221 return result.render(**self.d)
222
224 return """
225 _spacetreeId = treeNumber;
226 """
Default superclass for any data model in Peano which is stored within the grid.
Definition DaStGen2.py:197
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)