Peano 4
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, 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):
158 self._algorithm_steps_algorithm_steps["ReduceGlobalQuantities"].unprepare_traversal_kernel += value
159
161 """!
162
163 Create a repository of algorithmic steps which are then
164 ordered into the actual time stepping sequence.
165
166 """
167
168 PARTICLE = self.namenamename
169 CFL_FACTOR = self.cfl_factor
170 TIME_STEP_SIZE = self.initial_time_step_size
171
173 "ForceCalculation": AlgorithmStep(
174 name="ForceCalculation",
175 dependencies=AlgorithmStep.Dependencies.NEIGHBOURS,
176 effect=AlgorithmStep.Effect.ALTER_LOCAL_STATE,
177 touch_vertex_first_time_kernel="",
178 cell_kernel="",
179 touch_vertex_last_time_kernel="",
180 ),
181 "UpdatePositionAndVelocity": AlgorithmStep(
182 name="UpdatePositionAndVelocity",
183 dependencies=AlgorithmStep.Dependencies.SELF,
184 effect=AlgorithmStep.Effect.CHANGE_POSITION_OR_INTERACTION_RADIUS,
185 touch_vertex_first_time_kernel=f"""::swift2::kernels::forAllParticles( marker, assignedParticles, ::swift2::timestepping::resetMovedParticleMarker<globaldata::{PARTICLE}> );""",
186 touch_vertex_last_time_kernel=f"""
187 auto oldParticlePositions = ::toolbox::particles::assignmentchecks::recordParticlePositions(assignedParticles);
188 ::swift2::kernels::forAllParticles(marker, assignedParticles, ::swift2::timestepping::computeExplicitEulerWithGlobalTimeStepSize<globaldata::{PARTICLE}> );
189 ::toolbox::particles::assignmentchecks::traceParticleMovements(assignedParticles, oldParticlePositions, _spacetreeId);
190 """,
191 prepare_traversal_kernel=f"""::swift2::timestepping::computeAdmissibleTimeStepSizeFromGlobalMeshSizeAndMaximumVelocity<globaldata::{PARTICLE}>({CFL_FACTOR},{TIME_STEP_SIZE});""",
192 includes="""
193 #include "swift2/timestepping/Euler.h"
194 #include "swift2/timestepping/GlobalTimeStepping.h"
195 #include "swift2/timestepping/TimeStepping.h"
196 """,
197 ),
198 "ReduceVelocityAndDetermineTimeStepSize": AlgorithmStep(
199 name="ReduceVelocityAndDetermineTimeStepSize",
200 dependencies=AlgorithmStep.Dependencies.SELF,
201 effect=AlgorithmStep.Effect.CHANGE_POSITION_OR_INTERACTION_RADIUS,
202 prepare_traversal_kernel=f"""::swift2::timestepping::computeAdmissibleTimeStepSizeFromGlobalMeshSizeAndMaximumVelocity<globaldata::{PARTICLE}>({CFL_FACTOR},{TIME_STEP_SIZE});""",
203 includes="""
204 #include "swift2/timestepping/Euler.h"
205 #include "swift2/timestepping/GlobalTimeStepping.h"
206 #include "swift2/timestepping/TimeStepping.h"
207 """,
208 ),
209 "ReduceGlobalQuantities": AlgorithmStep(
210 name="ReduceGlobalQuantities",
211 dependencies=AlgorithmStep.Dependencies.SELF,
212 effect=AlgorithmStep.Effect.ALTER_GLOBAL_STATE,
213 touch_vertex_first_time_kernel=f"""::swift2::kernels::forAllParticles( marker, assignedParticles, ::swift2::statistics::reduceVelocityAndSearchRadius<globaldata::{PARTICLE}> );""",
214 prepare_traversal_kernel=f"""
215 globaldata::{PARTICLE}::getSpecies().clearSearchRadius();
216 globaldata::{PARTICLE}::getSpecies().clearVelocity();
217 """,
218 unprepare_traversal_kernel=f"""
219 globaldata::{PARTICLE}::getSpecies().allReduce();
220 globaldata::{PARTICLE}::getSpecies().setTimeStamp( globaldata::{PARTICLE}::getSpecies().getMinTimeStamp() + globaldata::{PARTICLE}::getSpecies().getMinTimeStepSize(), false );
221 ::swift2::statistics::reportSearchRadiusVTDt<globaldata::{PARTICLE}>( "{PARTICLE}" );
222 """,
223 includes="""
224 #include "swift2/statistics/Reports.h"
225 #include "swift2/statistics/Statistics.h"
226 """,
227 ),
228 }
229
231 """
232
233 The explicit Euler basically consists of two steps per particle. We first
234 determine the force. For this, we need access to the neighbours. The step
235 solely alters the individual particle's state. In the next algorithm step,
236 we need this state, as well as global data (the admissible time step size)
237 to update position and velocity. We also determine the CFL condition here.
238 So we
239
240 """
241 return [
242 self._algorithm_steps_algorithm_steps["ForceCalculation"],
243 self._algorithm_steps_algorithm_steps["UpdatePositionAndVelocity"],
244 self._algorithm_steps_algorithm_steps["ReduceGlobalQuantities"],
245 ]
246
248 """!
249
250 No particular initialisation required, but we reduce once, so we get
251 the initial stats right before we jump into the time stepping.
252
253 """
254 return [
255 self._algorithm_steps_algorithm_steps["ReduceVelocityAndDetermineTimeStepSize"],
256 ]
257
258 @property
260 return (
261 super(ExplicitEulerFixedSearchRadius, self).readme_descriptor
262 + """
263
264 Time integrator: Explicit Euler
265
266 - search radius: fixed
267 - CFL factor: """
268 + str(self.cfl_factor)
269 + """
270 - dt_initial: """
271 + str(self.initial_time_step_size)
272 + """
273
274 """
275 )
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