Peano
Loading...
Searching...
No Matches
PlotPatchesInPeanoBlockFormat.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
7
9 """!
10
11 Simple patch plotter
12
13 Very simple plotter that should be used in combination with Patches.
14 Patches with varying datatypes are supported via the "dataType" parameter,
15 but this defaults to doubles. This parameter should contain the C-style-
16 name of the type of the variable in the patch, e.g. float, double, etc.
17 This plotter works only for cell patches, i.e. patches associated with
18 faces or vertices are not supported.
19
20 At the moment, I can only plot one dataset (patch type) per plotter.
21 In theory, the underlying Peano plotter however could dump multiple
22 patches at once.
23
24 Also, this dump expects incoming data to be AoS.
25 """
26
27 def __init__(self,
28 filename,
29 patch,
30 dataset_name,
31 description, time_stamp_evaluation,
32 plot_cell_data=True,
33 metadata = "",
34 mapping = [],
35 guard="true",
36 additional_includes="",
37 precision=3,
38 select_dofs = None,
39 dataType="double",
40 restart_preprocess=False):
41 """!
42
43 Construct the block plotter
44
45 plot_cell_data: Boolean
46 Shall I plot cell data or vertex data. If you map the patches onto
47 vertex data, then I have to decrease the dofs pre axis, as we basically
48 plot the dual grid.
49
50 description: String
51
52 mapping: Series of d-tuples which describe how to distort quadrature/sampling
53 points within a reference cube/square. Can be empty alternatively.
54
55 select_dofs: [Int] or None
56 You can make the plotter only plot some of the dofs of interest
57
58 """
59 super(PlotPatchesInPeanoBlockFormat,self).__init__(descend_invocation_order=1,parallel=False)
60
61 valid_datatypes = {"float", "double", "long double", "_Float16", "std::float16_t", "__bf16", "std::bfloat16_t"}
62
63 self._plot_cell_data = plot_cell_data
64
65 self.d = {}
66 self.d[ "FILENAME" ] = filename
67 self.d[ "GUARD_PREDICATE" ] = guard
68
69 self.additional_includes = additional_includes
70
71 dofs_per_axis = patch.dim[0]
72
73 self.d[ "DOFS_PER_AXIS" ] = str(dofs_per_axis)
74
75 if select_dofs==None:
76 self.d[ "PLOTTED_UNKNOWNS" ] = str(patch.no_of_unknowns)
77 else:
78 self.d[ "PLOTTED_UNKNOWNS" ] = str(len(select_dofs))
79 self.d[ "UNKNOWNS" ] = str(patch.no_of_unknowns)
80 self.d[ "SELECT_DOFS" ] = select_dofs
81
82 self.d[ "NAME" ] = dataset_name
83 self.d[ "DESCRIPTION" ] = description
84 self.d[ "METADATA" ] = metadata
85 if len(mapping)==0:
86 self.d[ "MAPPING_2D"] = "double* mapping = nullptr;"
87 self.d[ "MAPPING_3D"] = "double* mapping = nullptr;"
88 else:
89 counter = 0
90 self.d[ "MAPPING_2D"] = "double mapping[" + str(2*dofs_per_axis*dofs_per_axis) + "] = {"
91 self.d[ "MAPPING_3D"] = "double mapping[" + str(3*dofs_per_axis*dofs_per_axis*dofs_per_axis) + "] = {"
92 for i in mapping:
93 if counter>0:
94 separator = ", "
95 else:
96 separator = " "
97 if counter<dofs_per_axis*dofs_per_axis:
98 self.d[ "MAPPING_2D"] += separator + str(i[0])
99 self.d[ "MAPPING_2D"] += ", " + str(i[1])
100 self.d[ "MAPPING_2D"] += "\n"
101 self.d[ "MAPPING_3D"] += separator + str(i[0])
102 self.d[ "MAPPING_3D"] += ", " + str(i[1])
103 if len(i)>2:
104 self.d[ "MAPPING_3D"] += ", " + str(i[2])
105 else:
106 self.d[ "MAPPING_3D"] += ", 0.0"
107 self.d[ "MAPPING_3D"] += "\n"
108 counter += 1
109
110 self.d[ "MAPPING_2D"] += "};"
111 self.d[ "MAPPING_3D"] += "};"
112
113 for i in patch.dim:
114 if i!=patch.dim[0]:
115 print( "Error: patch plotter requires patch to have same dimension along all coordinate axes")
116
117 if dataType not in valid_datatypes:
118 raise Exception("Chosen datatype " + dataType + " for plotting of patches is not a recognized choice.")
119
120 self.d[ "PRECISION" ] = precision
121 self.d[ "DATATYPE" ] = dataType
122 self.d[ "TIMESTAMP" ] = time_stamp_evaluation
123
124 self._restart_preprocess = restart_preprocess
125
126
127 __Template_Constructor = """
128 _writer = nullptr;
129 _dataWriter = nullptr;
130 _treeNumber = treeNumber;
131
132 logDebug( "PlotGrid2PlotGridInPeanoBlockFormat1()", "created tree instance for " << treeNumber );
133"""
134
135
137 return self.__Template_Constructor.format(**self.d)
138
139
140 __Template_EndTraversal = """
141 assertion1( _dataWriter!=nullptr, _treeNumber );
142 assertion1( _writer!=nullptr, _treeNumber );
143
144 _dataWriter->close();
145 _writer->writeToFile();
146
147 delete _dataWriter;
148 delete _writer;
149
150 _dataWriter = nullptr;
151 _writer = nullptr;
152"""
153
154
156 return ""
157
158
160 return " return std::vector< peano4::grid::GridControlEvent >();\n"
161
162
164 return __name__.replace(".py", "").replace(".", "_")
165
166
168 return False
169
170
171 __Template_TouchCellFirstTime_CellPlot = """
172 if ( {{GUARD_PREDICATE}} ) {
173 int vertexIndices[TwoPowerD];
174
175 const double PatchScaling = 1.0;
176
177 assertion( _writer!=nullptr );
178 assertion( _dataWriter!=nullptr );
179
180 const int patchIndex = _writer->plotPatch(
181 marker.x() - marker.h() * PatchScaling * 0.5,
182 marker.h() * PatchScaling
183 );
184
185 int cellIndex = _dataWriter->getFirstCellWithinPatch(patchIndex);
186 int currentDoF = 0;
187
188 dfor(k,{{DOFS_PER_AXIS}}) {
189 {% if SELECT_DOFS==None %}
190 {{DATATYPE}}* data = fineGridCell{{NAME}}.value + currentDoF;
191 {% else %}
192 {{DATATYPE}} data[] = {
193 fineGridCell{{NAME}}.value[ currentDoF + {{SELECT_DOFS[0]}} ]
194 {% for i in SELECT_DOFS[1:] %}
195 , fineGridCell{{NAME}}.value[ currentDoF + {{i}} ]
196 {% endfor %}
197 };
198 {% endif %}
199 _dataWriter->plotCell( cellIndex, data );
200 cellIndex++;
201 currentDoF += {{UNKNOWNS}};
202 }
203 }
204"""
205
206# self.d[ "SELECT_DOFS" ] = select_dofs
207
208
209 __Template_TouchCellFirstTime_VertexPlot = """
210 if ( {{GUARD_PREDICATE}} ) {
211 int vertexIndices[TwoPowerD];
212
213 const double PatchScaling = 1.0;
214
215 assertion( _writer!=nullptr );
216 assertion( _dataWriter!=nullptr );
217
218 const int patchIndex = _writer->plotPatch(
219 marker.x() - marker.h() * PatchScaling * 0.5,
220 marker.h() * PatchScaling
221 );
222
223 int vertexIndex = _dataWriter->getFirstVertexWithinPatch(patchIndex);
224 int currentDoF = 0;
225
226 dfor(k,{{DOFS_PER_AXIS}}) {
227 {% if SELECT_DOFS==None %}
228 {{DATATYPE}}* data = fineGridCell{{NAME}}.value + currentDoF;
229 {% else %}
230 {{DATATYPE}} data[] = {
231 fineGridCell{{NAME}}.value[ currentDoF + {{SELECT_DOFS[0]}} ]
232 {% for i in SELECT_DOFS[1:] %}
233 , fineGridCell{{NAME}}.value[ currentDoF + {{i}} ]
234 {% endfor %}
235 };
236 {% endif %}
237 _dataWriter->plotVertex( vertexIndex, data );
238 vertexIndex++;
239 currentDoF += {{UNKNOWNS}};
240 }
241 }
242"""
243
244 __Template_BeginTraversal_Generic = """
245 std::ostringstream snapshotFileName;
246 snapshotFileName << "{{FILENAME}}-" << counter;
247
248 if (tarch::mpi::Rank::getInstance().getNumberOfRanks()>1 ) {
249 snapshotFileName << "-rank-" << tarch::mpi::Rank::getInstance().getRank();
250 }
251
252 _writer = new tarch::plotter::griddata::blockstructured::PeanoTextPatchFileWriter(
253 Dimensions, snapshotFileName.str(), "{{FILENAME}}",
254 tarch::plotter::griddata::blockstructured::PeanoTextPatchFileWriter::IndexFileMode::AppendNewData,
255 {{TIMESTAMP}}
256 );
257
258 #if Dimensions==2
259 {{MAPPING_2D}}
260 #else
261 {{MAPPING_3D}}
262 #endif
263"""
264
265 __Template_BeginTraversal_Generic_Restart = """
266 tarch::mpi::Lock lock( _semaphore );
267
268 static int counter = -1;
269 counter++;
270
271 static bool preprocessFinished=false;
272 if (not preprocessFinished){
273 if ( tarch::mpi::Rank::getInstance().isGlobalMaster()){
274 counter=tarch::plotter::griddata::blockstructured::restartPreprocess("{{FILENAME}}", CheckpointTimeStamp);
275 }
276 MPI_Bcast(&counter, 1, MPI_INT, 0, MPI_COMM_WORLD);
277 preprocessFinished=true;
278 }
279
280"""+__Template_BeginTraversal_Generic
281
282 __Template_BeginTraversal_Generic = """
283 tarch::mpi::Lock lock( _semaphore );
284
285 static int counter = -1;
286 counter++;
287
288"""+__Template_BeginTraversal_Generic
289
290
291 __Template_BeginTraversal_CellPlot = __Template_BeginTraversal_Generic + """
292 _dataWriter = _writer->createCellDataWriter( "{{NAME}}", {{DOFS_PER_AXIS}}, {{PLOTTED_UNKNOWNS}}, "{{DESCRIPTION}}", "{{METADATA}}", mapping );
293 _dataWriter->setPrecision( {{PRECISION}} );
294"""
295 __Template_BeginTraversal_CellPlot_Restart = __Template_BeginTraversal_Generic_Restart + """
296 _dataWriter = _writer->createCellDataWriter( "{{NAME}}", {{DOFS_PER_AXIS}}, {{PLOTTED_UNKNOWNS}}, "{{DESCRIPTION}}", "{{METADATA}}", mapping );
297 _dataWriter->setPrecision( {{PRECISION}} );
298"""
299
300 __Template_BeginTraversal_VertexPlot = __Template_BeginTraversal_Generic + """
301 _dataWriter = _writer->createVertexDataWriter( "{{NAME}}", {{DOFS_PER_AXIS}}, {{PLOTTED_UNKNOWNS}}, "{{DESCRIPTION}}", "{{METADATA}}", mapping );
302 _dataWriter->setPrecision( {{PRECISION}} );
303"""
304 __Template_BeginTraversal_VertexPlot_Restart = __Template_BeginTraversal_Generic_Restart + """
305 _dataWriter = _writer->createVertexDataWriter( "{{NAME}}", {{DOFS_PER_AXIS}}, {{PLOTTED_UNKNOWNS}}, "{{DESCRIPTION}}", "{{METADATA}}", mapping );
306 _dataWriter->setPrecision( {{PRECISION}} );
307"""
308
309 def get_body_of_operation(self,operation_name):
310 result = "\n"
311 if operation_name==ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME and self._plot_cell_data:
312 result = jinja2.Template( self.__Template_TouchCellFirstTime_CellPlot ).render(**self.d)
313 if operation_name==ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME and not self._plot_cell_data:
314 result = jinja2.Template( self.__Template_TouchCellFirstTime_VertexPlot ).render(**self.d)
315
316 if operation_name==ActionSet.OPERATION_BEGIN_TRAVERSAL and self._plot_cell_data:
317 if self._restart_preprocess:
318 result = jinja2.Template( self.__Template_BeginTraversal_CellPlot_Restart ).render(**self.d)
319 else:
320 result = jinja2.Template( self.__Template_BeginTraversal_CellPlot ).render(**self.d)
321
322 if operation_name==ActionSet.OPERATION_BEGIN_TRAVERSAL and not self._plot_cell_data:
323 if self._restart_preprocess:
324 result = jinja2.Template( self.__Template_BeginTraversal_VertexPlot_Restart ).render(**self.d)
325 else:
326 result = jinja2.Template( self.__Template_BeginTraversal_VertexPlot ).render(**self.d)
327
328 if operation_name==ActionSet.OPERATION_END_TRAVERSAL:
329 result = jinja2.Template( self.__Template_EndTraversal ).render(**self.d)
330 return result
331
332
333 def get_attributes(self):
334 if self._plot_cell_data:
335 return """
336 static tarch::mpi::BooleanSemaphore _semaphore;
337
338 int _treeNumber;
339
340 tarch::plotter::griddata::blockstructured::PeanoTextPatchFileWriter* _writer;
341 tarch::plotter::griddata::blockstructured::PeanoTextPatchFileWriter::CellDataWriter* _dataWriter;
342"""
343 else:
344 return """
345 static tarch::mpi::BooleanSemaphore _semaphore;
346
347 int _treeNumber;
348
349 tarch::plotter::griddata::blockstructured::PeanoTextPatchFileWriter* _writer;
350 tarch::plotter::griddata::blockstructured::PeanoTextPatchFileWriter::VertexDataWriter* _dataWriter;
351"""
352
353
354 def get_includes(self):
355 return """
356#include "tarch/plotter/griddata/blockstructured/PeanoTextPatchFileWriter.h"
357#include "tarch/multicore/Lock.h"
358#include "tarch/multicore/BooleanSemaphore.h"
359#include "tarch/mpi/Lock.h"
360#include "tarch/mpi/BooleanSemaphore.h"
361#include "peano4/utils/Loop.h"
362#include "peano4/parallel/SpacetreeSet.h"
363""" + self.additional_includes
364
365
366 def get_static_initialisations(self,full_qualified_classname):
367 return """
368tarch::mpi::BooleanSemaphore """ + full_qualified_classname + """::_semaphore;
369"""
370
Action set (reactions to events)
Definition ActionSet.py:6
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.
__init__(self, filename, patch, dataset_name, description, time_stamp_evaluation, plot_cell_data=True, metadata="", mapping=[], guard="true", additional_includes="", precision=3, select_dofs=None, dataType="double", restart_preprocess=False)
Construct the block plotter.