Peano
Loading...
Searching...
No Matches
InsertParticlesByCoordinates.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
14 self, particle_set, coordinates, initialisation_call, additional_includes=""
15 ):
16 """
17
18 particle_set: ParticleSet
19
20 N: number of particles
21
22 coordinates: [ [Float,Float,Float] ]
23 Coordinates for the particle. So you can write
24
25 coordinates=[ [0.0,0.0,0.0], [0.2,0.2,0.0]]
26
27 for example to insert two particles. The code will create two particles.
28 This variant will work with 2d and 3d compiles, where the third
29 coordinate is ignored if you compile in 2d. If you pass in 2d coordinates,
30 then the code will fail (assertion) if you try to compile it in 3d.
31
32 initialisation_call: String (C++ code snippet)
33 Arbitrary code snippet which can work over a pointer particle. The object
34 to which this pointer points to is properly allocated, and its
35 coordinates are set. Furthermore, the object's search radius is
36 initialised with zero. You can alter the particle attributes now, i.e.
37 initialise the domain-specific data. Please also ensure you assign the
38 particle a proper search (interaction) radius if the radius is of
39 relevance for your application.
40
41 """
42 super(InsertParticlesByCoordinates, self).__init__(
43 descend_invocation_order=1, parallel=False
44 )
45
46 self.d = {}
47 self.d["PARTICLE"] = particle_set.particle_model.name
48 self.d["PARTICLES_CONTAINER"] = particle_set.name
49 self.d["N"] = len(coordinates)
50 self.d["INITIALISATION_CALL"] = initialisation_call
51
52 self._coordinates = coordinates
53 self.additional_includes = additional_includes
54
55 __Template_TouchCellFirstTime = jinja2.Template(
56 """
57
58 for(int i=0;i<{{N}};i++){
59 // It is important to have this asymmetric comparisons with <= as we
60 // need to ensure that particles right in the centre are either associated
61 // with the vertex left or right.
62 if (
63 not marker.willBeRefined()
64 and
65 marker.isContained(_coordinates[i])
66 ) {
67 globaldata::{{PARTICLE}}* particle = new globaldata::{{PARTICLE}}();
68
69 toolbox::particles::init(*particle,_coordinates[i],0.0);
70
71 // See documentation of constructor on initialisation snippet
72 {{INITIALISATION_CALL}}
73
74 toolbox::particles::insertParticleIntoCell(
75 marker,
76 particle,
77 fineGridVertices{{PARTICLES_CONTAINER}},
78 _spacetreeId
79 );
80 }
81 }
82"""
83 )
84
85 def get_body_of_operation(self, operation_name):
86 result = "\n"
87 if operation_name == ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME:
88 result = self.__Template_TouchCellFirstTime.render(**self.d)
89 return result
90
92 return " return std::vector< peano4::grid::GridControlEvent >();\n"
93
95 return __name__.replace(".py", "").replace(".", "_")
96
98 return False
99
100 def get_includes(self):
101 result = jinja2.Template(
102 """
103#include "tarch/multicore/Lock.h"
104#include "vertexdata/{{PARTICLES_CONTAINER}}.h"
105#include "globaldata/{{PARTICLE}}.h"
106#include "toolbox/particles/particles.h"
107#include "toolbox/particles/ParticleFactory.h"
108"""
110 )
111 return result.render(**self.d)
112
114 """!
115
116 Initialise the coordinates
117
118 This routine initialises the coordinates array, but it does so if and only
119 if this hasn't been done yet. Each tree traversal creates its own action
120 set. However, it would be ridiculously stupid to create the coordinates
121 multiple times. Rather, I
122
123 """
124 result = (
125 """
126_spacetreeId = treeNumber;
127
128#pragma clang optimize off
129tarch::multicore::Lock lock (_coordinatesSemaphore);
130if (_coordinates==nullptr) {
131 _coordinates = new tarch::la::Vector<Dimensions,double>["""
132 + str(self.d["N"])
133 + """];
134
135 """
136 )
137 dimensions = -1
138 for i in range(self.d["N"]):
139 if len(self._coordinates[i]) == 3:
140 result += (
141 " _coordinates["
142 + str(i)
143 + "](0)="
144 + str(self._coordinates[i][0])
145 + ";\n"
146 )
147 result += (
148 " _coordinates["
149 + str(i)
150 + "](1)="
151 + str(self._coordinates[i][1])
152 + ";\n"
153 )
154 result += " #if Dimensions==3\n"
155 result += (
156 " _coordinates["
157 + str(i)
158 + "](2)="
159 + str(self._coordinates[i][2])
160 + ";\n"
161 )
162 result += " #endif\n"
163 result += "\n"
164 assert (
165 dimensions == -1 or dimensions == 3
166 ), "inconsistent data: all coordinates have to have three entries: {}".format(
167 self._coordinates[i]
168 )
169 dimensions = 3
170 if len(self._coordinates[i]) == 2:
171 result += (
172 " _coordinates["
173 + str(i)
174 + "](0)="
175 + str(self._coordinates[i][0])
176 + ";\n"
177 )
178 result += (
179 " _coordinates["
180 + str(i)
181 + "](1)="
182 + str(self._coordinates[i][1])
183 + ";\n"
184 )
185 result += " assertion(Dimensions==2);\n"
186 result += "\n"
187 assert (
188 dimensions == -1 or dimensions == 2
189 ), "inconsistent data: all coordinates have to have three entries: {}".format(
190 self._coordinates[i]
191 )
192 dimensions = 2
193 result += """
194}
195#pragma clang optimize on
196"""
197 return result
198
199 def get_static_initialisations(self, full_qualified_classname):
200 return (
201 """
202tarch::la::Vector<Dimensions,double>* """
203 + full_qualified_classname
204 + """::_coordinates = nullptr;
205tarch::multicore::BooleanSemaphore """
206 + full_qualified_classname
207 + """::_coordinatesSemaphore;
208"""
209 )
210
211 def get_attributes(self):
212 return f"""
213 static tarch::multicore::BooleanSemaphore _coordinatesSemaphore;
214 static tarch::la::Vector<Dimensions,double>* _coordinates;
215
216 int _spacetreeId;
217"""
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, coordinates, initialisation_call, additional_includes="")
particle_set: ParticleSet
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
get_attributes(self)
Return attributes as copied and pasted into the generated class.