5from .Patch
import Patch
10 Helper class to capture all of the attributes we need for each
11 unknown, but were originally fixed to the PatchFileParser class
14 For instance, at time of writing the vis scripts cannot handle
15 displaying separate vtu files for different data that is produced
16 in Peano patch files. An excerpt:
19 offset 9.629630e-01 9.629630e-01
20 size 3.703704e-02 3.703704e-02
21 begin vertex-values "value"
24 begin vertex-values "rhs"
29 Previously, the only thing that would get parsed is the "value"
30 field, before moving on. We aim to get it to do the "rhs" part
33 However, we cannot assume that the number of dofs per axis or
34 unknowns per patch volume will be the same for both. So we
35 create this helper class to hold those.
37 We fix is_data_associated_to_cell to be the same as the
38 PatchFileParser object which, in turn, means they must
39 be the same for all of the unknowns
45 String of input file path (including filename and extension)
47 cell_data: list of patches
48 List of Patches with file data
54 Number of degrees of freedom per axis
57 Number of unknowns per patch volume
59 mapping: series of d-dimensional tuples
62 set_identifier: String
63 Can be empty to parse everything.
67 def __init__(self, unknown_name, dimensions, is_data_associated_to_cell):
82 assert self.
unknowns == 0,
"attribute already set!"
86 assert self.
dof == 0,
"attribute already set!"
93 assert not self.
cell_data,
"attribute already set!"
97 assert not self.
mapping,
"attribute already set!"
101 assert not self.
mapping,
"attribute already set!"
102 vertices_per_axis = self.
dof
104 vertices_per_axis += 1
106 for y
in range(vertices_per_axis):
107 for x
in range(vertices_per_axis):
108 self.
mapping.append(x * 1.0 / (vertices_per_axis - 1))
109 self.
mapping.append(y * 1.0 / (vertices_per_axis - 1))
111 for z
in range(vertices_per_axis):
112 for y
in range(vertices_per_axis):
113 for x
in range(vertices_per_axis):
114 self.
mapping.append(x * 1.0 / (vertices_per_axis - 1))
115 self.
mapping.append(y * 1.0 / (vertices_per_axis - 1))
116 self.
mapping.append(z * 1.0 / (vertices_per_axis - 1))
122 return f
"{self.unknown_name}: unknowns:{self.unknowns}, dof:{self.dof}"
127 Parser for Peano block file output.
129 This class should be instantiated from within the Visualiser class.
130 This class should be called once per patch file that contains
131 patch data that we want to render. The main method that is called
134 This method doesn't return anything. Rather, it sets unknown_attributes
135 to capture all the patch data for each of the unknowns that we find.
137 Then, the Visualiser class will steal this data, and combine it into
138 its own helper class.
144 String of input file path (including filename and extension)
149 mapping: series of d-dimensional tuples
152 set_identifier: String
153 Can be empty to parse everything.
155 unknown_attributes: Dict{ String, UnknownAttributes }
156 Dictionary that has the names of each unknown we wanna capture
157 as its keys, and the values are the helper class which captures
158 dimensions, cell data etc. Each of the unknowns should be
159 listed during the metadata part of the patch file, ie between
160 "begin cell-metadata" and "end cell-metadata".
163 def __init__(self, file_path, set_identifier, subdomain_number):
175 Here we expected the keys to be a list of unknown names that we
176 have associated with each cell/vertex, and the values to be
177 instances of the helper class UnknownAttributes
182 return f
"Parser for {self.file_path}, subdomain {self.subdomain_number}, identifier {self.set_identifier}"
186 Pass in file object, move it along and return it
189 unknown_name = current_line.strip().split()[-1][1:-1]
199 current_line = file_object.readline().strip()
201 use_default_mapping =
True
204 while not end_condition
in current_line:
205 if "number-of-unknowns" in current_line:
206 patch_unknown.set_unknowns(
int(current_line.strip().split()[1]))
207 if "number-of-dofs-per-axis" in current_line:
208 patch_unknown.set_dof(
int(current_line.strip().split()[1]))
209 if "description" in current_line:
210 patch_unknown.set_description(
211 current_line.strip().split(
"description")[1]
213 if '"' in patch_unknown.description:
215 "Warning: data description field "
216 + patch_unknown.description
217 +
" holds \" which might lead to issues with VTK's XML export. Remove them"
219 patch_unknown.description = patch_unknown.description.replace(
222 if "mapping" in current_line:
223 use_default_mapping =
False
224 values = current_line.strip().split(
"mapping")[1]
225 patch_unknown.set_mapping(np.fromstring(values, dtype=float, sep=
" "))
227 current_line = file_object.readline().strip()
229 if use_default_mapping:
230 patch_unknown._initialise_default_mapping_if_no_mapping_specified()
235 return file_object, current_line
238 self, current_line, file_object, end_condition="end patch"
241 Pass in file object, run it until we encounter the end condition,
244 We assume that current_line == "begin patch file" at this stage
246 This is where we read the actual data
250 current_line = file_object.readline().strip()
251 line = current_line.strip().split()
253 offset = (float(line[1]), float(line[2]))
255 offset = (float(line[1]), float(line[2]), float(line[3]))
258 current_line = file_object.readline().strip()
259 line = current_line.strip().split()
261 size = (float(line[1]), float(line[2]))
263 size = (float(line[1]), float(line[2]), float(line[3]))
267 while end_condition
not in current_line:
268 current_line = file_object.readline().strip()
273 if current_line.startswith(
"begin cell-values")
and (
279 ),
"is_data_associated_to_cell flag set incorrectly"
280 unknown_name = current_line.strip().split()[-1][1:-1]
281 current_line = file_object.readline()
282 values = np.fromstring(current_line, dtype=float, sep=
" ")
285 if current_line.startswith(
"begin vertex-values")
and (
291 ),
"is_data_associated_to_cell flag set incorrectly"
292 unknown_name = current_line.strip().split()[-1][1:-1]
293 current_line = file_object.readline()
294 values = np.fromstring(current_line, dtype=float, sep=
" ")
297 if values
is not None:
303 return file_object, current_line
307 Read file and return cell data, dimensions, number of degrees of freedom and number of unknowns
311 set_identifier: String
312 Name of the set of unknowns we want to extract. If this is the empty string
313 then I parse all content.
315 @todo: clean up the loop below. we can separate into getting metadata, and then reading patches
320 with open(self.
file_path,
"r")
as data_file:
321 current_line = data_file.readline()
325 the reason we keep track of 2 variables current_line and
326 line is because we want current_line to eval to False when we reach
327 EOF. However, we need to strip the whitespaces and newline
328 characters off the line for the data processing, without
329 exiting the loop if we have empty lines.
331 current_line = data_file.readline()
332 stripped_line = current_line.strip()
333 if stripped_line.startswith(
"dimensions"):
338 ],
"Only 2d and 3d patches are supported"
341 if stripped_line.startswith(
"begin cell-metadata")
and (
348 stripped_line, data_file,
"end cell-metadata"
351 if stripped_line.startswith(
"begin vertex-metadata")
and (
358 stripped_line, data_file,
"end vertex-metadata"
361 elif stripped_line.startswith(
"begin patch"):
366 stripped_line, data_file
371 except Exception
as e:
373 "Error: was not able to read "
389 We need to call the render function for each filter
390 on a variety of attributes, and then return them if they
393 We do this in a functional style, ie the Visualiser class
394 contains all of the filters we wish to apply, and we pass
395 the render function that we intend to use back to this
396 layer. Ugly, but we need to do some looping over the
397 different unknowns we see in the patch files, and I thought
398 it best to hide that from the parse_snapshot region of
401 The same apply for the validate function from the Visualiser
410 unknown_data.cell_data,
412 unknown_data.dimensions,
413 unknown_data.unknowns,
414 unknown_data.is_data_associated_to_cell,
415 unknown_data.description,
416 unknown_data.mapping,
417 ) = render_or_validate(
418 unknown_data.cell_data,
420 unknown_data.dimensions,
421 unknown_data.unknowns,
422 unknown_data.is_data_associated_to_cell,
423 unknown_data.description,
424 unknown_data.mapping,