faster tetgen reads
@@ -4,7 +4,6 @@ I/O for the TetGen file format, c.f.
"""
import logging
import os
-from itertools import islice
import numpy
@@ -24,51 +23,42 @@ def read(filename):
# read nodes
with open(node_filename) as f:
- line = next(islice(f, 1)).strip()
+ line = f.readline().strip()
while len(line) == 0 or line[0] == "#":
- line = next(islice(f, 1)).strip()
+ line = f.readline().strip()
num_points, dim, num_attrs, num_bmarkers = [
int(item) for item in line.split(" ") if item != ""
]
assert dim == 3
- flt = numpy.vectorize(float)
- points = numpy.empty((num_points, 3), dtype=float)
- for k in range(num_points):
- line = next(islice(f, 1)).strip()
- if len(line) == 0 or line[0] == "#":
- continue
-
- out = [item for item in line.split(" ") if item != ""]
- assert len(out) == 4 + num_attrs + num_bmarkers
- points[k] = flt(out[1:4])
- if k == 0:
- node_index_base = int(out[0])
+
+ points = numpy.fromfile(
+ f, dtype=float, count=(4 + num_attrs + num_bmarkers) * num_points, sep=" "
+ ).reshape(num_points, 4 + num_attrs + num_bmarkers)
+
+ node_index_base = int(points[0, 0])
# make sure the nodes a numbered consecutively
- assert int(out[0]) == node_index_base + k
- # discard the attributes and boundary markers
+ assert numpy.all(
+ points[:, 0] == numpy.arange(node_index_base, node_index_base + points.shape[0])
+ )
+ # remove the leading index column, the attributes, and the boundary markers
+ points = points[:, 1:4]
# read elements
with open(ele_filename) as f:
- line = next(islice(f, 1)).strip()
+ line = f.readline().strip()
while len(line) == 0 or line[0] == "#":
- line = next(islice(f, 1)).strip()
+ line = f.readline().strip()
num_tets, num_points_per_tet, num_attrs = [
int(item) for item in line.strip().split(" ") if item != ""
]
assert num_points_per_tet == 4
- cells = numpy.empty((num_tets, 4), dtype=int)
- for k in range(num_tets):
- line = next(islice(f, 1)).strip()
- if len(line) == 0 or line[0] == "#":
- continue
-
- out = [item for item in line.split(" ") if item != ""]
- assert len(out) == 5 + num_attrs
- cells[k] = [int(item) for item in out[1:5]]
- # discard the attributes
-
+ cells = numpy.fromfile(
+ f, dtype=int, count=(5 + num_attrs) * num_tets, sep=" "
+ ).reshape(num_tets, 5 + num_attrs)
+ # remove the leading index column and the attributes
+ cells = cells[:, 1:5]
cells -= node_index_base
return Mesh(points, {"tetra": cells})
