Peano
Loading...
Searching...
No Matches
DumpTracerIntoDatabase.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
6
7import jinja2
8
9
11 """!
12
13 Dump the tracer data into a csv database
14
15 This action set is to be added to you code if you want to dump tracer data
16 into a database. By default, Peano supports csv files. Please consult the
17 constructor for information on the configuration of these dumps: The dumps
18 are not synchronised with normal IO, but we keep track of the particles/tracers and
19 allow codes to dump updated particle data whenver some attributes or the
20 tracer position changes significantly. The term significantly can be controlled
21 via relative deltas through the constructor.
22
23 This class uses the C++ class toolbox::particles::TrajectoryDatabase from the
24 particles toolbox to realise the actual storage.
25
26 """
27
29 self,
30 particle_set,
31 solver,
32 filename,
33 number_of_entries_between_two_db_flushes=65536,
34 data_delta_between_two_snapsots=1e-8,
35 position_delta_between_two_snapsots=1e-8,
36 time_delta_between_two_snapsots=0,
37 output_precision=8,
38 clear_database_after_flush=True,
39 use_relative_deltas=False,
40 initial_record_time=-1,
41 last_record_time=1e8,
42 ):
43 """!
44
45 Constructor
46
47 data_delta_between_two_snapsots: Float
48 See toolbox::particles::TrajectoryDatabase::TrajectoryDatabase(). The
49 argument maps 1:1 to the constructor's argument dataDelta.
50
51 This flag has no impact whatsoever how often the data is dumped into a
52 file. The frequency of datafile writes is solely controlled via
53 number_of_entries_between_two_db_flushes.
54
55 position_delta_between_two_snapsots: Float
56 See toolbox::particles::TrajectoryDatabase::TrajectoryDatabase(). The
57 argument maps 1:1 to the constructor's argument positionDelta.
58
59 This flag has no impact whatsoever how often the data is dumped into a
60 file. The frequency of datafile writes is solely controlled via
61 number_of_entries_between_two_db_flushes.
62
63 time_delta_between_two_snapsots: Float
64 See toolbox::particles::TrajectoryDatabase::TrajectoryDatabase(). The
65 argument maps 1:1 to the constructor's argument timeDelta.
66
67 This flag has no impact whatsoever how often the data is dumped into a
68 file. The frequency of datafile writes is solely controlled via
69 number_of_entries_between_two_db_flushes.
70
71 number_of_entries_between_two_db_flushes: Int
72 See toolbox::particles::TrajectoryDatabase::TrajectoryDatabase(). The
73 argument maps 1:1 to the constructor's argument growthBetweenTwoDatabaseFlushes.
74
75 use_relative_deltas: Boolean
76 See description of C++ class in toolbox::particles::TrajectoryDatabase
77
78 initial_record_time: Float
79 you can specify from when does the tracer start to dump data to files.
80
81 last_record_time: Float
82 you can specify at when does the tracer stop dumping data to files.
83
84 clear_database_after_flush: Boolean
85 """
86 super(DumpTracerIntoDatabase, self).__init__(descend_invocation_order=1, parallel=False)
87 self.d = {}
88 self.d["PARTICLE"] = particle_set.particle_model.name
89 self.d["PARTICLES_CONTAINER"] = particle_set.name
90 self.d["DATA_DELTA"] = data_delta_between_two_snapsots
91 self.d["POSITION_DELTA"] = position_delta_between_two_snapsots
92 self.d["TIME_DELTA"] = time_delta_between_two_snapsots
93 self.d["OUTPUT_PRECISION"] = output_precision
94 self.d["FILENAME"] = filename
95 self.d["SOLVER_NAME"] = solver._name
96 self.d["SOLVER_INSTANCE"] = solver.get_name_of_global_instance()
97 if use_relative_deltas:
98 self.d["USE_RELATIVE_DELTAS"] = "true"
99 else:
100 self.d["USE_RELATIVE_DELTAS"] = "false"
101 if clear_database_after_flush:
102 self.d["CLEAR_DATABASE_AFTER_FLUSH"] = "true"
103 else:
104 self.d["CLEAR_DATABASE_AFTER_FLUSH"] = "false"
105
106 self.d["INI_RECORD"] = initial_record_time
107 self.d["LAST_RECORD"] = last_record_time
108
110 number_of_entries_between_two_db_flushes
111 )
112
113 __Template_TouchCellLastTime = jinja2.Template(
114 """
115if (
116 not marker.willBeRefined()
117 and
118 fineGridCell{{SOLVER_NAME}}CellLabel.getHasUpdated()
119 and
120 repositories::{{SOLVER_INSTANCE}}.isLastGridSweepOfTimeStep()
121) {
122 double IniRecord={{INI_RECORD}};
123 double LastRecord={{LAST_RECORD}};
124 for (int i=0; i<TwoPowerD; i++) {
125 for (auto* p: fineGridVertices{{PARTICLES_CONTAINER}}(i) ) {
126 if (
127 p->getParallelState()==globaldata::{{PARTICLE}}::ParallelState::Local
128 and
129 marker.isContained( p->getX() )
130 and
131 fineGridCell{{SOLVER_NAME}}CellLabel.getTimeStamp()>=IniRecord
132 and
133 fineGridCell{{SOLVER_NAME}}CellLabel.getTimeStamp()<=LastRecord
134 ) {
135 _database.addParticleSnapshot(
136 p->getNumber(0),
137 p->getNumber(1),
138 fineGridCell{{SOLVER_NAME}}CellLabel.getTimeStamp(),
139 p->getX(),
140 p->getData().size(),
141 p->getData().data()
142 );
143 }
144 }
145 }
146}
147"""
148 )
149
150 def get_body_of_operation(self, operation_name):
151 result = ""
152 if operation_name == ActionSet.OPERATION_TOUCH_CELL_LAST_TIME:
153 result = self.__Template_TouchCellLastTime.render(**self.d)
154 return result
155
157 return __name__.replace(".py", "").replace(".", "_")
158
160 return False
161
163 template = jinja2.Template(
164 """
165 _database.setOutputFileName( "{{FILENAME}}" );
166 _database.setOutputPrecision( {{OUTPUT_PRECISION}} );
167 _database.setDataDeltaBetweenTwoSnapshots( {{DATA_DELTA}}, {{USE_RELATIVE_DELTAS}} );
168 _database.setPositionDeltaBetweenTwoSnapshots( {{POSITION_DELTA}}, {{USE_RELATIVE_DELTAS}} );
169 _database.setTimeDeltaBetweenTwoSnapshots( {{TIME_DELTA}} );
170 _database.clearDatabaseAfterFlush( {{CLEAR_DATABASE_AFTER_FLUSH}} );
171"""
172 )
173 return template.render(**self.d)
174
175 def get_includes(self):
176 result = jinja2.Template(
177 """
178#include "toolbox/particles/TrajectoryDatabase.h"
179#include "vertexdata/{{PARTICLES_CONTAINER}}.h"
180#include "globaldata/{{PARTICLE}}.h"
181#include "peano4/parallel/Node.h"
182#include "repositories/SolverRepository.h"
183"""
184 )
185 return result.render(**self.d)
186
187 def get_attributes(self):
188 return """
189 static toolbox::particles::TrajectoryDatabase _database;
190"""
191
192 def get_static_initialisations(self, full_qualified_classname):
193 return (
194 """
195toolbox::particles::TrajectoryDatabase """
196 + full_qualified_classname
197 + """::_database( """
199 + """);
200"""
201 )
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
user_should_modify_template(self)
Is the user allowed to modify the output.
__init__(self, particle_set, solver, filename, number_of_entries_between_two_db_flushes=65536, data_delta_between_two_snapsots=1e-8, position_delta_between_two_snapsots=1e-8, time_delta_between_two_snapsots=0, output_precision=8, clear_database_after_flush=True, use_relative_deltas=False, initial_record_time=-1, last_record_time=1e8)
Constructor.
get_includes(self)
Return include statements that you need.
get_attributes(self)
Return attributes as copied and pasted into the generated class.
Action set (reactions to events)
Definition ActionSet.py:6