From babf79e6b380016b1849ec4be775cadabe4f8f7f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 1 Aug 2023 02:49:36 +0000 Subject: [PATCH 1/3] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.8.0 → v3.10.1](https://github.com/asottile/pyupgrade/compare/v3.8.0...v3.10.1) - [github.com/psf/black: 23.3.0 → 23.7.0](https://github.com/psf/black/compare/23.3.0...23.7.0) - [github.com/PyCQA/flake8: 6.0.0 → 6.1.0](https://github.com/PyCQA/flake8/compare/6.0.0...6.1.0) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0d17b6842..67d6de27c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/asottile/pyupgrade - rev: "v3.8.0" + rev: "v3.10.1" hooks: - id: pyupgrade args: [--py36-plus] @@ -38,13 +38,13 @@ repos: - id: isort - repo: https://github.com/psf/black - rev: "23.3.0" + rev: "23.7.0" hooks: - id: black args: [--line-length=79] - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 args: [--extend-ignore=E203] From dc9bb9335f87704901d7e5ee92cbf6da9c2afdd0 Mon Sep 17 00:00:00 2001 From: "Pohlmann, Roxana" Date: Fri, 4 Aug 2023 18:11:28 +0200 Subject: [PATCH 2/3] Add npz export for gustaf entities --- examples/export_npz.py | 115 ++++++++++++++++++++++++++++++++ gustaf/io/__init__.py | 11 +-- gustaf/io/default.py | 3 +- gustaf/io/npz.py | 147 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 266 insertions(+), 10 deletions(-) create mode 100644 examples/export_npz.py create mode 100644 gustaf/io/npz.py diff --git a/examples/export_npz.py b/examples/export_npz.py new file mode 100644 index 000000000..40edb611f --- /dev/null +++ b/examples/export_npz.py @@ -0,0 +1,115 @@ +import numpy as np + +import gustaf + +if __name__ == "__main__": + # Define coordinates + vertices = np.array( + [ + [0.0, 0.0, 0.0], + [1.0, 0.0, 0.0], + [0.0, 1.0, 0.0], + [1.0, 1.0, 0.0], + [0.0, 0.0, 1.0], + [1.0, 0.0, 1.0], + [0.0, 1.0, 1.0], + [1.0, 1.0, 1.0], + ] + ) + + # Define hexa connectivity + hv = np.array([[0, 1, 3, 2, 4, 5, 7, 6]]) + + # Init hexa elements + hexa = gustaf.Volumes( + vertices=vertices, + volumes=hv, + ) + + # Define tet connectivity + tv = np.array( + [ + [0, 2, 7, 3], + [0, 2, 6, 7], + [0, 6, 4, 7], + [5, 0, 4, 7], + [5, 0, 7, 1], + [7, 0, 3, 1], + ] + ) + + # Create tetra elements and set vertex data + tet = gustaf.Volumes(vertices=vertices, volumes=tv) + tet.vertex_data["arange"] = -np.arange(len(vertices)) + tet.BC = {"min_z": np.array([0, 1, 2, 3]), "max_z": np.array([4, 5, 6, 7])} + + # Create hexa elements and set vertex data + hexa.vertex_data["arange"] = np.arange(len(vertices)) + hexa.vertex_data["quad_x"] = [v[0] ** 2 for v in vertices] + hexa.BC = { + "min_z": np.array([0, 1, 2, 3]), + "max_z": np.array([4, 5, 6, 7]), + } + + hexa.show_options["data_name"] = "arange" + + # Export hexa, edges and vertices + gustaf.io.npz.export(hexa, "export/hexa.npz") + gustaf.io.npz.export(hexa.to_edges(), "export/hexa_edges.npz") + gustaf.io.npz.export(hexa.to_vertices(), "export/hexa_vertices.npz") + + # Load hexa files + load_hexa = gustaf.io.npz.load("export/hexa.npz") + load_edges = gustaf.io.npz.load("export/hexa_edges.npz") + load_verts = gustaf.io.npz.load("export/hexa_vertices.npz") + + # Show original and loaded file + # Show options are not exported and have to be reset + gustaf.show( + ["Original hexa", hexa], + ["Loaded hexa (show options must be set again)", load_hexa], + ) + + # Show the expored edges and vertices + gustaf.show( + ["Exported edges", load_edges], + ["Exported vertices", load_verts], + [ + "Exported hexa with indicated boundary nodes", + load_hexa, + gustaf.Vertices(load_hexa.vertices[load_hexa.BC["min_z"]]), + gustaf.Vertices(load_hexa.vertices[load_hexa.BC["max_z"]]), + ], + ) + + # Vertex data has to be set for edges and vertices as to_edges() and + # to_vertices() does not copy it + load_hexa.show_options["data_name"] = "arange" + + load_edges.vertex_data["quad_x"] = hexa.vertex_data["quad_x"] + load_edges.show_options["data_name"] = "quad_x" + + load_verts.vertex_data["arange"] = hexa.vertex_data["arange"] + load_verts.show_options["data_name"] = "arange" + + # Show colored vertices + gustaf.show( + ["Show entities with copied data", load_hexa], load_edges, load_verts + ) + + # Export tetra files + gustaf.io.npz.export(tet, "export/tet.npz") + gustaf.io.npz.export(tet.to_edges(), "export/tet_edges.npz") + gustaf.io.npz.export(tet.to_vertices(), "export/tet_vertices.npz") + + # Load tetra files with default load function + load_tet = gustaf.io.load("export/tet.npz") + load_tet_edges = gustaf.io.load("export/tet_edges.npz") + load_tet_verts = gustaf.io.load("export/tet_vertices.npz") + + # Show tetras + gustaf.show( + ["Tetra", load_tet], + ["Tetra edges", load_tet_edges], + ["Tetra vertices", load_verts], + ) diff --git a/gustaf/io/__init__.py b/gustaf/io/__init__.py index 6359ac409..d043c979c 100644 --- a/gustaf/io/__init__.py +++ b/gustaf/io/__init__.py @@ -5,14 +5,7 @@ O - `export`. """ -from gustaf.io import ioutils, meshio, mfem, mixd, nutils +from gustaf.io import ioutils, meshio, mfem, mixd, npz, nutils from gustaf.io.default import load -__all__ = [ - "ioutils", - "mfem", - "meshio", - "mixd", - "nutils", - "load", -] +__all__ = ["ioutils", "mfem", "meshio", "mixd", "nutils", "load", "npz"] diff --git a/gustaf/io/default.py b/gustaf/io/default.py index b15b16952..f32ee6955 100644 --- a/gustaf/io/default.py +++ b/gustaf/io/default.py @@ -1,6 +1,6 @@ import pathlib -from gustaf.io import meshio, mfem, mixd +from gustaf.io import meshio, mfem, mixd, npz def load(fname): @@ -22,6 +22,7 @@ def load(fname): ".mixd": mixd.load, ".mfem": mfem.load, ".msh": meshio.load, + ".npz": npz.load, } fname = pathlib.Path(fname).resolve() diff --git a/gustaf/io/npz.py b/gustaf/io/npz.py new file mode 100644 index 000000000..3197c1715 --- /dev/null +++ b/gustaf/io/npz.py @@ -0,0 +1,147 @@ +import numpy as np + +from gustaf.edges import Edges +from gustaf.faces import Faces +from gustaf.vertices import Vertices +from gustaf.volumes import Volumes + + +def load(fname, **kwargs): + """ + Read gus_object from `.npz` file. + + .. code-block:: python + + tet = gustaf.io.npz.load('export/tet.npz') + tet.show() + + Returns + -------- + gus_object: gustaf entity + Can be vertices, Edges, Faces or Volumes + """ + + # Load the file and check entity type + loaded = np.load(fname, **kwargs) + dict_keys = list(loaded.keys()) + whatami = str(loaded["whatami"]) + + gus_object_types = { + "edges": Edges, + "tri": Faces, + "quad": Faces, + "tet": Volumes, + "hexa": Volumes, + } + + # Vertices + if whatami == "vertices": + gus_object = Vertices(vertices=loaded["vertices"]) + # Meshes + elif whatami in gus_object_types.keys(): + gus_object = gus_object_types[whatami]( + vertices=loaded["vertices"], elements=loaded["elements"] + ) + # Unknown types + else: + raise ValueError(f"Type {whatami} is not supported in gustaf.") + + for key in dict_keys: + # Load vertex data + if key.startswith("vertex_data-"): + gus_object.vertex_data[key.removeprefix("vertex_data-")] = loaded[ + key + ] + # Load boundaries + elif key.startswith("BC-"): + gus_object.BC[key.removeprefix("BC-")] = loaded[key] + + return gus_object + + +def export(gus_object, fname): + """ + Save a gustaf object (Vertices, Edges, Faces or Volumes) as a `npz`-file. + The export file contains (if applicable): vertices, elements, vertex data, + BC. + The `npz`-format is a compressed numpy format + https://numpy.org/doc/stable/reference/generated/numpy.savez.html . + + .. code-block:: python + + import gustaf + import numpy as np + + # Define coordinates + vertices = np.array( + [ + [0.0, 0.0, 0.0], + [1.0, 0.0, 0.0], + [0.0, 1.0, 0.0], + [1.0, 1.0, 0.0], + [0.0, 0.0, 1.0], + [1.0, 0.0, 1.0], + [0.0, 1.0, 1.0], + [1.0, 1.0, 1.0], + ] + ) + + # Define hexa connectivity + hv = np.array([[0, 1, 3, 2, 4, 5, 7, 6]]) + + # Init hexa elements + hexa = gustaf.Volumes( + vertices=vertices, + volumes=hv, + ) + + # Create hexa elements and set vertex data + hexa.vertex_data['arange'] = np.arange(len(vertices)) + hexa.vertex_data['quad_x'] = [v[0]**2 for v in vertices] + hexa.BC = {'min_z' : np.array([0, 1, 2, 3]), + 'max_z' : np.array([4, 5, 6, 7])} + + # Export hexa + gustaf.io.npz.export(hexa, 'export/hexa.npz') + + Parameters + ----------- + gus_object: gustaf entity + fname: str + Export filename with `npz` suffix + + Returns + -------- + None + """ + + if not fname.endswith(".npz"): + raise ValueError("The filename must end with .npz.") + + property_dicts = { + "whatami": gus_object.whatami, + "vertices": gus_object.vertices, + } + + # Include elements for meshes + if type(gus_object) in [Edges, Faces, Volumes]: + property_dicts["elements"] = gus_object.elements + + # Export vertex data + property_dicts.update( + { + f"vertex_data-{key}": item + for key, item in gus_object.vertex_data.items() + } + ) + + # In case of faces and volumes, export the boundaries + if type(gus_object) in [Faces, Volumes]: + property_dicts.update( + {f"BC-{key}": item for key, item in gus_object.BC.items()} + ) + + np.savez( + fname, + **property_dicts, + ) From 987b384053d8211fbf34d7f6b19e32b9ab141475 Mon Sep 17 00:00:00 2001 From: "Pohlmann, Roxana" Date: Fri, 4 Aug 2023 18:16:04 +0200 Subject: [PATCH 3/3] Add creation of direcotry, if it doesnt exist --- examples/export_npz.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/export_npz.py b/examples/export_npz.py index 40edb611f..a3a2cdecf 100644 --- a/examples/export_npz.py +++ b/examples/export_npz.py @@ -1,3 +1,5 @@ +from pathlib import Path + import numpy as np import gustaf @@ -54,6 +56,7 @@ hexa.show_options["data_name"] = "arange" # Export hexa, edges and vertices + Path("export").mkdir(exist_ok=True) gustaf.io.npz.export(hexa, "export/hexa.npz") gustaf.io.npz.export(hexa.to_edges(), "export/hexa_edges.npz") gustaf.io.npz.export(hexa.to_vertices(), "export/hexa_vertices.npz")