Peano
Loading...
Searching...
No Matches
Step.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
4
5from peano4.solversteps.StepToActionSet import StepToActionSet
6from peano4.solversteps.StepToObserver import StepToObserver
7
8
9#
10# @todo Aufteilen in mehrere Files mit ToXXXXX wie im Model.
11#
12# TODO MLADEN: Ist der Kommentar oben noch aktuell?
13
14
15class Step:
16 """!
17
18 One step
19
20 Most generic version of a solver step. A solverstep describes what Peano 4
21 should do when it runs over the grid. As users have to specify which pieces
22 of data from the data model are used by the solver step, it can handle all
23 the user data stack flow.
24
25 This class also is responsible to generate all function signatures of all
26 the steps, observers and action sets. In the Peano terminology, a step
27 corresponds to an observer. For any given step, we run through the mesh
28 and pass the traversal automaton an observer which accepts events (aka
29 state transition observations).
30
31 It is the observer's job to then distribute these observations, broken
32 down into grid actions such as "touch vertex first time", among the action
33 sets that are tied to this observer. In Python you can have one action set
34 and associate it with several observers. In the C++ code, we will flatten
35 such a relation, i.e. create the corresponding action set multiple times.
36
37 @see peano4.solversteps.ActionSet
38
39 name: String
40 This name is used to create the underlying action set later on
41 """
42
43 def __init__(self,
44 name,
45 add_user_defined_actions=True,
46 ):
47 """
48 By default, the step generates at least one action set for the user.
49 However, you can disable this behaviour by passing False to
50 add_user_defined_actions. Alternatively, use remove_all_action_sets()
51 on the step.
52 """
53 self.name = name
54 self.cell_data = []
55 self.face_data = []
56 self.vertex_data = []
57 if add_user_defined_actions:
59 else:
60 self.action_sets = []
63
65 """
66 Each step holds a set of actions. They describe what the step actually
67 should do whenever it loads a vertex, runs into a cell, and so forth. By
68 default, the step holds one user-defined actions which means
69 that a stub is generated where users can insert their functionality. You
70 can remove this one (or any other one added so far) with this routine.
71 """
72 self.action_sets = []
73
74 def __sort(self):
75 """!
76
77 Simple bubble sort the action sets, such that their descend_invocation_order
78 is preserved.
79
80 @see peano4.solversteps.ActionSet.descend_invocation_order
81
82 """
83 for i in range(0, len(self.action_sets)):
84 for j in range(i + 1, len(self.action_sets)):
85 if (
86 self.action_sets[i].descend_invocation_order
87 > self.action_sets[j].descend_invocation_order
88 ):
89 tmp = self.action_sets[i]
90 self.action_sets[i] = self.action_sets[j]
91 self.action_sets[j] = tmp
92
93 def add_action_set(self, action_set):
94 """!
95
96 Add a new action set to this mesh traversal step
97
98 Each step holds a set of action_sets. They describe what the step actually
99 should do whenever it loads a vertex, runs into a cell, and so forth. By
100 default, the step holds one user-defined action_set (UserActionSet) which means
101 that a stub is generated where users can insert their functionality. It is
102 important in which order you add your action_sets: The whole tree traversal
103 is a top-down/depth-first tree traversal. So all the enter, create, ...
104 operations of a action_set are invoked exactly in the order you add them to
105 the step. All the delete, leave, ... operations are invokved in reversed
106 order.
107
108 I used to have a flag append_at_end with the default True, but this one is
109 now replaced, as each action set knows its priority.
110 """
111 self.action_sets.append(action_set)
112 self.__sort()
113
114 def set_project(self, project):
115 """!
116
117 Tie step to project
118
119 You don't have to call this. It is automatically called once you add a step
120 to the project's steps.
121 """
122 self.project = project
123 self.namespace = project.namespace
124 self.subdirectory = project.subdirectory
125
126 def use_cell(self, submodel):
127 self.cell_data.append(submodel)
128
129 def use_face(self, submodel):
130 self.face_data.append(submodel)
131
132 def use_vertex(self, submodel):
133 self.vertex_data.append(submodel)
134
136 """!
137
138 Return max descend_invocation_order over all action sets associated with this step.
139
140 @see peano4.solversteps.ActionSet.descend_invocation_order
141
142 """
143 self.__sort()
144 if len(self.action_sets) == 0:
145 return 0
146 return self.action_sets[-1].descend_invocation_order
147
149 """!
150
151 Return minimum descend_invocation_order over all action sets associated with this step.
152
153 @see peano4.solversteps.ActionSet.descend_invocation_order
154
155 """
156 self.__sort()
157 if len(self.action_sets) == 0:
158 return 0
159 return self.action_sets[0].descend_invocation_order
160
162 result = ["marker", "const peano4::datamanagement::VertexMarker&"]
163 for i in self.vertex_data:
164 result += ["fineGridVertex" + i.name, i.get_full_qualified_type() + "&"]
165 for i in self.vertex_data:
166 result += ["coarseGridVertices" + i.name, i.get_enumeration_type() + ""]
167 for i in self.face_data:
168 result += ["coarseGridFaces" + i.name, i.get_enumeration_type() + ""]
169 for i in self.cell_data:
170 result += ["coarseGridCell" + i.name, i.get_full_qualified_type() + "&"]
171 return result
172
174 result = ["marker", "const peano4::datamanagement::FaceMarker&"]
175 for i in self.vertex_data:
176 result += ["fineGridVertices" + i.name, i.get_enumeration_type() + ""]
177 for i in self.face_data:
178 result += ["fineGridFace" + i.name, i.get_full_qualified_type() + "&"]
179 for i in self.vertex_data:
180 result += ["coarseGridVertices" + i.name, i.get_enumeration_type() + ""]
181 for i in self.face_data:
182 result += ["coarseGridFaces" + i.name, i.get_enumeration_type() + ""]
183 for i in self.cell_data:
184 result += ["coarseGridCell" + i.name, i.get_full_qualified_type() + "&"]
185 return result
186
188 result = ["marker", "const peano4::datamanagement::CellMarker&"]
189 for i in self.vertex_data:
190 result += ["fineGridVertices" + i.name, i.get_enumeration_type() + ""]
191 for i in self.face_data:
192 result += ["fineGridFaces" + i.name, i.get_enumeration_type() + ""]
193 for i in self.cell_data:
194 result += ["fineGridCell" + i.name, i.get_full_qualified_type() + "&"]
195 for i in self.vertex_data:
196 result += ["coarseGridVertices" + i.name, i.get_enumeration_type() + ""]
197 for i in self.face_data:
198 result += ["coarseGridFaces" + i.name, i.get_enumeration_type() + ""]
199 for i in self.cell_data:
200 result += ["coarseGridCell" + i.name, i.get_full_qualified_type() + "&"]
201 return result
202
204 result = ["marker", "const peano4::datamanagement::CellMarker&"]
205 for i in self.vertex_data:
206 result += ["fineGridVertices" + i.name, i.get_enumeration_type() + ""]
207 for i in self.face_data:
208 result += ["fineGridFaces" + i.name, i.get_enumeration_type() + ""]
209 for i in self.cell_data:
210 result += ["fineGridCell" + i.name, i.get_full_qualified_type() + "&"]
211
212 for i in self.vertex_data:
213 result += ["coarseGridVertices" + i.name, i.get_enumeration_type() + ""]
214 for i in self.face_data:
215 result += ["coarseGridFaces" + i.name, i.get_enumeration_type() + ""]
216 for i in self.cell_data:
217 result += ["coarseGridCell" + i.name, i.get_full_qualified_type() + "&"]
218
219 return result
220
221 def construct_output(self, output):
222 """
223 Each solver step basically gives us two big files/classes: A class which
224 handles the actual data movements, i.e. is an implementation of the tree
225 visitor pattern over the Peano4 tree. The other type is an interface which
226 provides plugin points into the created data transitions from a user's
227 perspective.
228 """
229
230 included_action_sets = []
231 for action_set in self.action_sets:
232 full_qualified_action_set_name = self.action_set_generator.construct_output(
233 output, action_set
234 )
235 included_action_sets.append(full_qualified_action_set_name)
236
237 self.observer_generator.construct_output(output, included_action_sets)
238
239 def copy_action_sets_from_other_step(self, other_step):
240 self.action_sets += other_step.action_sets
highest_descend_invocation_order(self)
Return max descend_invocation_order over all action sets associated with this step.
Definition Step.py:135
get_vertex_operations_signature(self)
Definition Step.py:161
get_face_operations_signature(self)
Definition Step.py:173
set_project(self, project)
Tie step to project.
Definition Step.py:114
use_vertex(self, submodel)
Definition Step.py:132
lowest_descend_invocation_order(self)
Return minimum descend_invocation_order over all action sets associated with this step.
Definition Step.py:148
construct_output(self, output)
Each solver step basically gives us two big files/classes: A class which handles the actual data move...
Definition Step.py:221
__init__(self, name, add_user_defined_actions=True)
By default, the step generates at least one action set for the user.
Definition Step.py:46
use_face(self, submodel)
Definition Step.py:129
use_cell(self, submodel)
Definition Step.py:126
get_cell_operations_signature(self)
Definition Step.py:187
remove_all_actions(self)
Each step holds a set of actions.
Definition Step.py:64
copy_action_sets_from_other_step(self, other_step)
Definition Step.py:239
__sort(self)
Simple bubble sort the action sets, such that their descend_invocation_order is preserved.
Definition Step.py:74
add_action_set(self, action_set)
Add a new action set to this mesh traversal step.
Definition Step.py:93