diff --git a/setup.cfg b/setup.cfg index 422674df0..5051729f9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = meshio -version = 5.2.4 +version = 5.2.5 author = Nico Schlömer et al. author_email = nico.schloemer@gmail.com description = I/O for many mesh formats diff --git a/src/meshio/_mesh.py b/src/meshio/_mesh.py index 65646d349..da897d814 100644 --- a/src/meshio/_mesh.py +++ b/src/meshio/_mesh.py @@ -313,7 +313,7 @@ def read(cls, path_or_buf, file_format=None): warn("meshio.Mesh.read is deprecated, use meshio.read instead") return read(path_or_buf, file_format) - def sets_to_int_data(self): + def cell_sets_to_data(self): # If possible, convert cell sets to integer cell data. This is possible if all # cells appear exactly in one group. default_value = -1 @@ -341,8 +341,10 @@ def sets_to_int_data(self): self.cell_data[data_name] = intfun self.cell_sets = {} + def point_sets_to_data(self): # now for the point sets # Go for -1 as the default value. (NaN is not int.) + default_value = -1 if len(self.point_sets) > 0: intfun = np.full(len(self.points), default_value, dtype=int) for i, cc in enumerate(self.point_sets.values()): @@ -358,73 +360,61 @@ def sets_to_int_data(self): self.point_data[data_name] = intfun self.point_sets = {} - def int_data_to_sets(self, keys: list[str] | None = None): - """Convert all int data to {point,cell}_sets, where possible.""" - rm_keys = [] - for key, data in self.cell_data.items(): - if keys is not None: - if key not in keys: - continue - - # handle all int and uint data - if not all(v.dtype.kind in ["i", "u"] for v in data): - continue - - rm_keys.append(key) - - # this call can be rather expensive - tags = np.unique(np.concatenate(data)) - - # try and get the names by splitting the key along "-" (this is how - # sets_to_int_data() forms the key) - names = key.split("-") - # remove duplicates and preserve order - # : - names = list(dict.fromkeys(names)) - if len(names) != len(tags): - # alternative names - names = [f"set-{key}-{tag}" for tag in tags] - - # TODO there's probably a better way besides np.where, something from - # np.unique or np.sort - for name, tag in zip(names, tags): - self.cell_sets[name] = [np.where(d == tag)[0] for d in data] + # This used to be int_data_to_sets(), converting _all_ cell and point data. + # This is not useful in many cases, as one usually only wants one + # particular data array (e.g., "MaterialIDs") converted to sets. + def cell_data_to_sets(self, key: str): + """Convert point_data to cell_sets.""" + data = self.cell_data[key] + + # handle all int and uint data + if not all(v.dtype.kind in ["i", "u"] for v in data): + raise RuntimeError(f"cell_data['{key}'] is not int data.") + + tags = np.unique(np.concatenate(data)) + + # try and get the names by splitting the key along "-" (this is how + # sets_to_int_data() forms the key) + names = key.split("-") + # remove duplicates and preserve order + # : + names = list(dict.fromkeys(names)) + if len(names) != len(tags): + # alternative names + names = [f"set-{key}-{tag}" for tag in tags] + + # TODO there's probably a better way besides np.where, something from + # np.unique or np.sort + for name, tag in zip(names, tags): + self.cell_sets[name] = [np.where(d == tag)[0] for d in data] # remove the cell data - for key in rm_keys: - del self.cell_data[key] - - # now point data - rm_keys = [] - for key, data in self.point_data.items(): - if keys is not None: - if key not in keys: - continue + del self.cell_data[key] - # handle all int and uint data - if not all(v.dtype.kind in ["i", "u"] for v in data): - continue + def point_data_to_sets(self, key: str): + """Convert point_data to point_sets.""" + data = self.point_data[key] - rm_keys.append(key) + # handle all int and uint data + if not all(v.dtype.kind in ["i", "u"] for v in data): + raise RuntimeError(f"point_data['{key}'] is not int data.") - # this call can be rather expensive - tags = np.unique(data) + tags = np.unique(data) - # try and get the names by splitting the key along "-" (this is how - # sets_to_int_data() forms the key - names = key.split("-") - # remove duplicates and preserve order - # : - names = list(dict.fromkeys(names)) - if len(names) != len(tags): - # alternative names - names = [f"set{tag}" for tag in tags] + # try and get the names by splitting the key along "-" (this is how + # sets_to_int_data() forms the key + names = key.split("-") + # remove duplicates and preserve order + # : + names = list(dict.fromkeys(names)) + if len(names) != len(tags): + # alternative names + names = [f"set-key-{tag}" for tag in tags] - # TODO there's probably a better way besides np.where, something from - # np.unique or np.sort - for name, tag in zip(names, tags): - self.point_sets[name] = np.where(data == tag)[0] + # TODO there's probably a better way besides np.where, something from + # np.unique or np.sort + for name, tag in zip(names, tags): + self.point_sets[name] = np.where(data == tag)[0] # remove the cell data - for key in rm_keys: - del self.point_data[key] + del self.point_data[key] diff --git a/tests/test_mesh.py b/tests/test_mesh.py index af10fc502..33a573532 100644 --- a/tests/test_mesh.py +++ b/tests/test_mesh.py @@ -30,7 +30,8 @@ def test_sets_to_int_data(): mesh = helpers.add_point_sets(mesh) mesh = helpers.add_cell_sets(mesh) - mesh.sets_to_int_data() + mesh.point_sets_to_data() + mesh.cell_sets_to_data() assert mesh.cell_sets == {} assert_equal(mesh.cell_data, {"grain0-grain1": [[0, 0, 1, 1, 1]]}) @@ -39,7 +40,8 @@ def test_sets_to_int_data(): assert_equal(mesh.point_data, {"fixed-loose": [0, 0, 0, 1, 1, 1, 1]}) # now back to set data - mesh.int_data_to_sets() + mesh.cell_data_to_sets("grain0-grain1") + mesh.point_data_to_sets("fixed-loose") assert mesh.cell_data == {} assert_equal(mesh.cell_sets, {"grain0": [[0, 1]], "grain1": [[2, 3, 4]]}) @@ -56,7 +58,7 @@ def test_sets_to_int_data_warning(): cell_sets={"tag": [[0]]}, ) with pytest.warns(UserWarning): - mesh.sets_to_int_data() + mesh.cell_sets_to_data() assert np.all(mesh.cell_data["tag"] == np.array([[0, -1]])) mesh = meshio.Mesh( @@ -65,7 +67,7 @@ def test_sets_to_int_data_warning(): point_sets={"tag": [[0, 1, 3]]}, ) with pytest.warns(UserWarning): - mesh.sets_to_int_data() + mesh.point_sets_to_data() assert np.all(mesh.point_data["tag"] == np.array([[0, 0, -1, 0]])) @@ -74,7 +76,7 @@ def test_int_data_to_sets(): mesh = helpers.tri_mesh mesh.cell_data = {"grain0-grain1": [np.array([0, 1])]} - mesh.int_data_to_sets() + mesh.cell_data_to_sets("grain0-grain1") assert_equal(mesh.cell_sets, {"grain0": [[0]], "grain1": [[1]]}) @@ -92,8 +94,8 @@ def test_gh_1165(): }, ) - mesh.sets_to_int_data() - mesh.int_data_to_sets() + mesh.cell_sets_to_data() + mesh.cell_data_to_sets("test-sets") assert_equal(mesh.cell_sets, {"test": [[], [1]], "sets": [[0, 1], [0, 2, 3]]})