15 Most generic version of a solver step. A solverstep describes what Peano 4
16 should do when it runs over the grid. As users have to specify which pieces
17 of data from the data model are used by the solver step, it can handle all
18 the user data stack flow.
20 This class also is responsible to generate all function signatures of all
21 the steps, observers and action sets. In the Peano terminology, a step
22 corresponds to an observer. For any given step, we run through the mesh
23 and pass the traversal automaton an observer which accepts events (aka
24 state transition observations).
26 It is the observer's job to then distribute these observations, broken
27 down into grid actions such as "touch vertex first time", among the action
28 sets that are tied to this observer. In Python you can have one action set
29 and associate it with several observers. In the C++ code, we will flatten
30 such a relation, i.e. create the corresponding action set multiple times.
32 @see @ref peano4.api.solversteps.ActionSet.ActionSet
35 This name is used to create the underlying action set later on
40 add_user_defined_actions=True,
43 By default, the step generates at least one action set for the user.
44 However, you can disable this behaviour by passing False to
45 add_user_defined_actions. Alternatively, use remove_all_action_sets()
65 if add_user_defined_actions:
75 Class name of the observer this step is translated into. This is
76 the step's name, cut down to 64 characters plus a consecutive number
77 if it is longer (@see peano4.api.output.Helper.shortened_class_name()),
78 as the class name also is the observer's file name. Everybody
79 referring to the observer class, such as the generated runners, has
80 to use this getter rather than the step's name.
86 return shortened_class_name(self.
name, max_length=64)
90 Each step holds a set of actions. They describe what the step actually
91 should do whenever it loads a vertex, runs into a cell, and so forth. By
92 default, the step holds one user-defined actions which means
93 that a stub is generated where users can insert their functionality. You
94 can remove this one (or any other one added so far) with this routine.
101 Simple bubble sort the action sets, such that their descend_invocation_order
104 @see @ref peano4.api.solversteps.ActionSet.ActionSet.descend_invocation_order
120 Add a new action set to this mesh traversal step
122 Each step holds a set of action_sets. They describe what the step actually
123 should do whenever it loads a vertex, runs into a cell, and so forth. By
124 default, the step holds one user-defined action_set (UserActionSet) which means
125 that a stub is generated where users can insert their functionality. It is
126 important in which order you add your action_sets: The whole tree traversal
127 is a top-down/depth-first tree traversal. So all the enter, create, ...
128 operations of a action_set are invoked exactly in the order you add them to
129 the step. All the delete, leave, ... operations are invokved in reversed
132 I used to have a flag append_at_end with the default True, but this one is
133 now replaced, as each action set knows its priority.
143 You don't have to call this. It is automatically called once you add a step
144 to the project's steps.
162 Return max descend_invocation_order over all action sets associated with this step.
164 @see @ref peano4.api.solversteps.ActionSet.ActionSet.descend_invocation_order
170 return self.
action_sets[-1].descend_invocation_order
175 Return minimum descend_invocation_order over all action sets associated with this step.
177 @see @ref peano4.api.solversteps.ActionSet.ActionSet.descend_invocation_order
183 return self.
action_sets[0].descend_invocation_order
186 result = [
"marker",
"const peano4::datamanagement::VertexMarker&"]
188 result += [
"fineGridVertex" + i.name, i.get_full_qualified_type() +
"&"]
190 result += [
"coarseGridVertices" + i.name, i.get_enumeration_type() +
""]
192 result += [
"coarseGridFaces" + i.name, i.get_enumeration_type() +
""]
194 result += [
"coarseGridCell" + i.name, i.get_full_qualified_type() +
"&"]
198 result = [
"marker",
"const peano4::datamanagement::FaceMarker&"]
200 result += [
"fineGridVertices" + i.name, i.get_enumeration_type() +
""]
202 result += [
"fineGridFace" + i.name, i.get_full_qualified_type() +
"&"]
204 result += [
"coarseGridVertices" + i.name, i.get_enumeration_type() +
""]
206 result += [
"coarseGridFaces" + i.name, i.get_enumeration_type() +
""]
208 result += [
"coarseGridCell" + i.name, i.get_full_qualified_type() +
"&"]
212 result = [
"marker",
"const peano4::datamanagement::CellMarker&"]
214 result += [
"fineGridVertices" + i.name, i.get_enumeration_type() +
""]
216 result += [
"fineGridFaces" + i.name, i.get_enumeration_type() +
""]
218 result += [
"fineGridCell" + i.name, i.get_full_qualified_type() +
"&"]
220 result += [
"coarseGridVertices" + i.name, i.get_enumeration_type() +
""]
222 result += [
"coarseGridFaces" + i.name, i.get_enumeration_type() +
""]
224 result += [
"coarseGridCell" + i.name, i.get_full_qualified_type() +
"&"]
228 result = [
"marker",
"const peano4::datamanagement::CellMarker&"]
230 result += [
"fineGridVertices" + i.name, i.get_enumeration_type() +
""]
232 result += [
"fineGridFaces" + i.name, i.get_enumeration_type() +
""]
234 result += [
"fineGridCell" + i.name, i.get_full_qualified_type() +
"&"]
237 result += [
"coarseGridVertices" + i.name, i.get_enumeration_type() +
""]
239 result += [
"coarseGridFaces" + i.name, i.get_enumeration_type() +
""]
241 result += [
"coarseGridCell" + i.name, i.get_full_qualified_type() +
"&"]
247 Each solver step basically gives us two big files/classes: A class which
248 handles the actual data movements, i.e. is an implementation of the tree
249 visitor pattern over the Peano4 tree. The other type is an interface which
250 provides plugin points into the created data transitions from a user's
254 @ref peano4.api.solversteps.SynchroniseActionSets.SynchroniseActionSets
255 yield no C++ code. They only separate the task groups which we hand
257 (@ref peano4.api.solversteps.SynchroniseActionSets.get_task_groups()).
260 included_action_sets = []
261 index_of_action_set = {}
263 if isinstance(action_set, SynchroniseActionSets):
268 index_of_action_set[id(action_set)] = len(included_action_sets)
269 included_action_sets.append(full_qualified_action_set_name)
272 [index_of_action_set[id(action_set)]
for action_set
in group]
Maps a step to an action set.
Take an action set and construct an observer from it.
__sort(self)
Simple bubble sort the action sets, such that their descend_invocation_order is preserved.
construct_output(self, output)
Each solver step basically gives us two big files/classes: A class which handles the actual data move...
add_action_set(self, action_set)
Add a new action set to this mesh traversal step.
use_vertex(self, submodel)
get_face_operations_signature(self)
remove_all_actions(self)
Each step holds a set of actions.
get_cell_operations_signature(self)
set_project(self, project)
Tie step to project.
__init__(self, name, add_user_defined_actions=True)
By default, the step generates at least one action set for the user.
get_touch_cell_signature(self)
highest_descend_invocation_order(self)
Return max descend_invocation_order over all action sets associated with this step.
copy_action_sets_from_other_step(self, other_step)
lowest_descend_invocation_order(self)
Return minimum descend_invocation_order over all action sets associated with this step.
str get_observer_class_name(self)
Class name of the observer this step is translated into.
get_vertex_operations_signature(self)
Marker which ends a group of action sets that run in parallel.