Peano
Loading...
Searching...
No Matches
ExplicitEulerFixedSearchRadius.py
Go to the documentation of this file.
1# This file is part of the SWIFT2 project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3from swift2.particle.Particle import Particle
4from swift2.particle.AlgorithmStep import AlgorithmStep
5
6import peano4
7
8from abc import ABC
9
10
12 """!
13
14 Simple particle with fixed search radius subject to explicit Euler
15
16 Simple particle with a fixed search radius H which moves according
17 to an explicit Euler. By default, the Euler uses global time stepping,
18 i.e. the combination of maximum velocity and minimal mesh size determines
19 the time step size of the subsequent time step. The term fixed means that
20 the search radius does not change throughout the time step. Nothing
21 stops you however to adopt the search radius in-between any two
22 time steps. However, only change the radius in a step which is marked with
23 the AlgorithmStep.Effect.CHANGE_POSITION_OR_INTERACTION_RADIUS.
24
25
26 Besides the default variables x and h, the particle has the following properties:
27
28 - a vector a which is the acceleration;
29 - a vector v which is the velocity.
30
31 You can add further properties via
32
33 myparticle.data.add_attribute( peano4.dastgen2.Peano4DoubleArray("myFancyArray","Dimensions") )
34
35 in your code. Or you can create a subclass which adds additional fields
36 after it has called the baseline constructor.
37
38
39 ## Force calculation
40
41 There is a dedicated algorithmic step to do all the force calculation. This
42 step can be tailored to your needs by setting the strings
43
44 - enter_cell_kernel
45 - touch_particles_of_set_first_time_kernel
46 - touch_particles_of_set_last_time_kernel
47
48 Each of these is unset (None) by default, but you can make it hold any
49 reasonable C++ string. The Swift2ish way to use them is ot use the
50 iterators from ParticleSetIterators.h to run over the relevant particles.
51
52 For the two vertex kernels, this would look similar to
53
54 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55 touch_vertex_first_time_kernel = "::swift2::kernels::forAllParticles( marker, assignedParticles, numberOfCoalescedAssignedParticles, myFunctor );"
56 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57
58 For the cell, it resembles
59
60 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
61 ::swift2::kernels::forAllParticlePairs( marker, localParticles, activeParticles, myFunction);
62 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63
64 The documentation of the actual operators ParticleBinaryOperator and
65 ParticleUnaryOperatorOnVertex for more documentation.
66
67
68 ## Attributes
69
70 name: String
71 To be in line with other conventions, I recommend you start with an
72 uppercase letter. This has to be a valid C++ identifier, i.e. don't
73 use any special symbols besides an underscore.
74
75
76
77
78
79 ## Attributes
80
81 name: String
82 To be in line with other conventions, I recommend you start with an
83 uppercase letter. This has to be a valid C++ identifier, i.e. don't
84 use any special symbols besides an underscore.
85
86 @see peano4::datamanagement::CellMarker
87 @see peano4::datamanagement::VertexMarker
88
89
90 @see peano4::datamanagement::CellMarker
91 @see peano4::datamanagement::VertexMarker
92
93 """
94
96 self,
97 name,
98 cfl_factor,
99 initial_time_step_size,
100 enter_cell_kernel="",
101 touch_particles_of_set_first_time_kernel="",
102 touch_particles_of_set_last_time_kernel="",
103 particles_per_cell=0,
104 min_h=0.005,
105 max_h=0.3,
106 ):
107 super(ExplicitEulerFixedSearchRadius, self).__init__(
108 name,
109 particles_per_cell,
110 min_h,
111 max_h,
112 )
113
116 self.data.add_attribute(self.velocity)
117 self.data.add_attribute(self.accelerator)
118
119 self.cfl_factor = cfl_factor
120 self.initial_time_step_size = initial_time_step_size
121
123
124 self.enter_cell_kernel = enter_cell_kernel
126 touch_particles_of_set_first_time_kernel
127 )
129 touch_particles_of_set_last_time_kernel
130 )
131 pass
132
133 @property
135 return self._algorithm_steps_algorithm_steps["ForceCalculation"].touch_vertex_first_time_kernel
136
137 @touch_particles_of_set_first_time_kernel.setter
139 self._algorithm_steps_algorithm_steps["ForceCalculation"].touch_vertex_first_time_kernel = value
140
141 @property
143 return self._algorithm_steps_algorithm_steps["ForceCalculation"].touch_vertex_last_time_kernel
144
145 @touch_particles_of_set_first_time_kernel.setter
147 self._algorithm_steps_algorithm_steps["ForceCalculation"].touch_vertex_last_time_kernel = value
148
149 @property
150 def cell_kernel(self):
151 return self._algorithm_steps_algorithm_steps["ForceCalculation"].cell_kernel
152
153 @cell_kernel.setter
154 def cell_kernel(self, value):
155 self._algorithm_steps_algorithm_steps["ForceCalculation"].cell_kernel = value
156
157 def add_to_reduction(self, value):
159 "ReduceGlobalQuantities"
160 ].unprepare_traversal_kernel += value
161
163 """!
164
165 Create a repository of algorithmic steps which are then
166 ordered into the actual time stepping sequence.
167
168 """
169
170 PARTICLE = self.namenamename
171 CFL_FACTOR = self.cfl_factor
172 TIME_STEP_SIZE = self.initial_time_step_size
173
175 "ForceCalculation": AlgorithmStep(
176 name="ForceCalculation",
177 dependencies=AlgorithmStep.Dependencies.NEIGHBOURS,
178 effect=AlgorithmStep.Effect.ALTER_LOCAL_STATE,
179 touch_vertex_first_time_kernel="",
180 cell_kernel="",
181 touch_vertex_last_time_kernel="",
182 ),
183 "UpdatePositionAndVelocity": AlgorithmStep(
184 name="UpdatePositionAndVelocity",
185 dependencies=AlgorithmStep.Dependencies.SELF,
186 effect=AlgorithmStep.Effect.CHANGE_POSITION_OR_INTERACTION_RADIUS,
187 touch_vertex_first_time_kernel=f"""::swift2::kernels::forAllParticles( marker, assignedParticles, numberOfCoalescedAssignedParticles, ::swift2::timestepping::resetMovedParticleMarker<globaldata::{PARTICLE}> );""",
188 touch_vertex_last_time_kernel=f"""
189 auto oldParticlePositions = ::toolbox::particles::assignmentchecks::recordParticlePositions(assignedParticles);
190 ::swift2::kernels::forAllParticles(marker, assignedParticles, numberOfCoalescedAssignedParticles, ::swift2::timestepping::computeExplicitEulerWithGlobalTimeStepSize<globaldata::{PARTICLE}> );
191 ::toolbox::particles::assignmentchecks::traceParticleMovements(assignedParticles, oldParticlePositions, marker.x(), marker.h(), _spacetreeId);
192 """,
193 prepare_traversal_kernel=f"""::swift2::timestepping::computeAdmissibleTimeStepSizeFromGlobalMeshSizeAndMaximumVelocity<globaldata::{PARTICLE}>({CFL_FACTOR},{TIME_STEP_SIZE});""",
194 includes="""
195 #include "swift2/timestepping/Euler.h"
196 #include "swift2/timestepping/GlobalTimeStepping.h"
197 #include "swift2/timestepping/TimeStepping.h"
198 """,
199 ),
200 "ReduceVelocityAndDetermineTimeStepSize": AlgorithmStep(
201 name="ReduceVelocityAndDetermineTimeStepSize",
202 dependencies=AlgorithmStep.Dependencies.SELF,
203 effect=AlgorithmStep.Effect.CHANGE_POSITION_OR_INTERACTION_RADIUS,
204 prepare_traversal_kernel=f"""::swift2::timestepping::computeAdmissibleTimeStepSizeFromGlobalMeshSizeAndMaximumVelocity<globaldata::{PARTICLE}>({CFL_FACTOR},{TIME_STEP_SIZE});""",
205 includes="""
206 #include "swift2/timestepping/Euler.h"
207 #include "swift2/timestepping/GlobalTimeStepping.h"
208 #include "swift2/timestepping/TimeStepping.h"
209 """,
210 ),
211 "ReduceGlobalQuantities": AlgorithmStep(
212 name="ReduceGlobalQuantities",
213 dependencies=AlgorithmStep.Dependencies.SELF,
214 effect=AlgorithmStep.Effect.ALTER_GLOBAL_STATE,
215 touch_vertex_first_time_kernel=f"""::swift2::kernels::forAllParticles( marker, assignedParticles, numberOfCoalescedAssignedParticles, numberOfCoalescedAssignedParticles, ::swift2::statistics::reduceVelocityAndSearchRadius<globaldata::{PARTICLE}> );""",
216 prepare_traversal_kernel=f"""
217 globaldata::{PARTICLE}::getSpecies().clearSearchRadius();
218 globaldata::{PARTICLE}::getSpecies().clearVelocity();
219 """,
220 unprepare_traversal_kernel=f"""
221 globaldata::{PARTICLE}::getSpecies().allReduce();
222 globaldata::{PARTICLE}::getSpecies().setTimeStamp( globaldata::{PARTICLE}::getSpecies().getMinTimeStamp() + globaldata::{PARTICLE}::getSpecies().getMinTimeStepSize(), false );
223 ::swift2::statistics::reportSearchRadiusVTDt<globaldata::{PARTICLE}>( "{PARTICLE}" );
224 """,
225 includes="""
226 #include "swift2/statistics/Reports.h"
227 #include "swift2/statistics/Statistics.h"
228 """,
229 ),
230 }
231
233 """
234
235 The explicit Euler basically consists of two steps per particle. We first
236 determine the force. For this, we need access to the neighbours. The step
237 solely alters the individual particle's state. In the next algorithm step,
238 we need this state, as well as global data (the admissible time step size)
239 to update position and velocity. We also determine the CFL condition here.
240 So we
241
242 """
243 return [
244 self._algorithm_steps_algorithm_steps["ForceCalculation"],
245 self._algorithm_steps_algorithm_steps["UpdatePositionAndVelocity"],
246 self._algorithm_steps_algorithm_steps["ReduceGlobalQuantities"],
247 ]
248
250 """!
251
252 No particular initialisation required, but we reduce once, so we get
253 the initial stats right before we jump into the time stepping.
254
255 """
256 return [
257 self._algorithm_steps_algorithm_steps["ReduceVelocityAndDetermineTimeStepSize"],
258 ]
259
260 @property
262 return (
263 super(ExplicitEulerFixedSearchRadius, self).readme_descriptor
264 + """
265
266 Time integrator: Explicit Euler
267
268 - search radius: fixed
269 - CFL factor: """
270 + str(self.cfl_factor)
271 + """
272 - dt_initial: """
273 + str(self.initial_time_step_size)
274 + """
275
276 """
277 )
Specialisation of dastgen2.attributes.DoubleArray which relies on Peano's tarch.
Defines the meta data around one algorithmic step per particle.
Simple particle with fixed search radius subject to explicit Euler.
initialisation_steps(self)
No particular initialisation required, but we reduce once, so we get the initial stats right before w...
__init__(self, name, cfl_factor, initial_time_step_size, enter_cell_kernel="", touch_particles_of_set_first_time_kernel="", touch_particles_of_set_last_time_kernel="", particles_per_cell=0, min_h=0.005, max_h=0.3)
Initialise the particle.
algorithm_steps(self)
The explicit Euler basically consists of two steps per particle.
__setup_algorithm_steps(self)
Create a repository of algorithmic steps which are then ordered into the actual time stepping sequenc...
Base class for any particle in the project.
Definition Particle.py:10