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 __Template_TouchVertexFirstTime = jinja2.Template(
98 """
99 {% if TOUCH_VERTEX_FIRST_COMPUTE_KERNEL!=None %}
100 auto& assignedParticles = fineGridVertex{{LOCAL_PARTICLES_CONTAINER}};
101 const int numberOfCoalescedAssignedParticles = -1;
102
103 {{TOUCH_VERTEX_FIRST_COMPUTE_KERNEL}}
104 {% endif %}
105"""
106 )
107
108 __Template_TouchVertexLastTime = jinja2.Template(
109 """
110 {% if TOUCH_VERTEX_LAST_COMPUTE_KERNEL!=None %}
111 auto& assignedParticles = fineGridVertex{{LOCAL_PARTICLES_CONTAINER}};
112 const int numberOfCoalescedAssignedParticles = -1;
113
114 {{TOUCH_VERTEX_LAST_COMPUTE_KERNEL}}
115 {% endif %}
116"""
117 )
118
119 __Template_TouchCellFirstTime = jinja2.Template(
120 """
121 // all are vectors, as they are all ordered so we can match the local flags
122 // with particles
123 std::list< globaldata::{{LOCAL_PARTICLE}}* > localParticles;
124 std::vector< int > numberOfCoalescedLocalParticlesPerVertex( TwoPowerD );
125 std::vector< int > _numberOfActiveParticlesPerVertex( TwoPowerD ); // stay compatible with coalesced version
126 std::vector< char > 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.push_back( 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.push_back( p );
146 }
147 }
148
149 {% if PARTICLE_CELL_UPDATE_KERNEL!=None %}
150 std::list< 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 _activeParticles.erase(
160 std::prev(_activeParticles.end(),fineGridVertices{{ACTIVE_PARTICLES_CONTAINER}}(i).size() ),
161 _activeParticles.end()
162 );
163 }
164"""
165 )
166
167 def get_body_of_operation(self, operation_name):
168 result = "\n"
169 # if operation_name==ActionSet.OPERATION_BEGIN_TRAVERSAL:
170 # result = self.__Template_BeginTraversal.render(**self.d)
171 if operation_name == ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
172 result = self.__Template_TouchCellFirstTime.render(**self.d)
173 if operation_name == ActionSet.OPERATION_TOUCH_CELL_LAST_TIME:
174 result = self.__Template_TouchCellLastTime.render(**self.d)
175 if operation_name == ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME:
176 result = self.__Template_TouchVertexFirstTime.render(**self.d)
177 if operation_name == ActionSet.OPERATION_TOUCH_VERTEX_LAST_TIME:
178 result = self.__Template_TouchVertexLastTime.render(**self.d)
179 return result
180
182 return " return std::vector< peano4::grid::GridControlEvent >();\n"
183
185 return self.d["PREPARE_TRAVERSAL_KERNEL"]
186
188 return self.d["UNPREPARE_TRAVERSAL_KERNEL"]
189
191 return __name__.replace(".py", "").replace(".", "_")
192
194 return False
195
196 def get_includes(self):
197 result = jinja2.Template(
198 """
199#include "tarch/multicore/Lock.h"
200#include "toolbox/particles/particles.h"
201#include "vertexdata/{{LOCAL_PARTICLES_CONTAINER}}.h"
202#include "globaldata/{{LOCAL_PARTICLE}}.h"
203#include "vertexdata/{{ACTIVE_PARTICLES_CONTAINER}}.h"
204#include "globaldata/{{ACTIVE_PARTICLE}}.h"
205
206{{ADDITIONAL_INCLUDES}}
207
208#include <unordered_set>
209#include <set>
210#include <vector>
211"""
212 )
213 return result.render(**self.d)
214
215 def get_attributes(self):
216 result = jinja2.Template(
217 """
218 std::list< globaldata::{{ACTIVE_PARTICLE}}* > _activeParticles;
219 int _spacetreeId;
220"""
221 )
222 return result.render(**self.d)
223
225 return """
226 _spacetreeId = treeNumber;
227 """
Default superclass for any data model in Peano which is stored within the grid.
Definition DaStGen2.py:157
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)