From 14697e4bfb1d3d02b3840f57ee7802a2e7bc42a0 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Tue, 21 May 2024 18:38:34 +0200 Subject: [PATCH 01/16] Add dpf_field_to_vtk in vtk_helper.py Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 88 ++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 9 deletions(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index 14030b163ce..36e51910a7d 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -1,5 +1,6 @@ import numpy as np import pyvista as pv +from typing import Union import ansys.dpf.core as dpf from ansys.dpf.core import errors from vtk import ( @@ -124,7 +125,7 @@ def __init__( ModuleNotFoundError.__init__(self, msg) -def dpf_mesh_to_vtk_op(mesh, nodes, as_linear): +def dpf_mesh_to_vtk_op(mesh, nodes=None, as_linear=True): """Return a pyvista unstructured grid given DPF node and element definitions from operators (server > 6.2) @@ -134,7 +135,7 @@ def dpf_mesh_to_vtk_op(mesh, nodes, as_linear): Meshed Region to export to pyVista format nodes : dpf.Field - Field containing the nodes of the mesh. + Field containing the node coordinates of the mesh. as_linear : bool Export quadratic surface elements as linear. @@ -333,25 +334,28 @@ def compute_offset(): return pv.UnstructuredGrid(offset, cells, vtk_cell_type, node_coordinates) -def dpf_mesh_to_vtk(mesh, nodes=None, as_linear=True): - """Return a pyvista unstructured grid given DPF node and element - definitions. +def dpf_mesh_to_vtk( + mesh: dpf.MeshedRegion, + nodes: Union[dpf.Field, None] = None, + as_linear: bool = True +) -> pv.UnstructuredGrid: + """Return a pyvista UnstructuredGrid given a pydpf MeshedRegion. Parameters ---------- mesh : dpf.MeshedRegion - Meshed Region to export to pyVista format + Meshed Region to export to pyVista format. nodes : dpf.Field, optional - Field containing the nodes of the mesh. + Field containing the node coordinates of the mesh (useful to get a deformed geometry). as_linear : bool, optional Export quadratic surface elements as linear. Returns ------- - grid : pyvista.UnstructuredGrid - Unstructured grid of the DPF mesh. + grid: + UnstructuredGrid corresponding to the DPF mesh. """ try: return dpf_mesh_to_vtk_op(mesh, nodes, as_linear) @@ -363,3 +367,69 @@ def vtk_update_coordinates(vtk_grid, coordinates_array): from copy import copy vtk_grid.points = copy(coordinates_array) + + +def dpf_field_to_vtk( + field: dpf.Field, + nodes: Union[dpf.Field, None] = None, + as_linear: bool = True +) -> pv.UnstructuredGrid: + """Return a pyvista UnstructuredGrid given a DPF Field. + + Parameters + ---------- + field: + Field to export to pyVista format. + + nodes: + Field containing the node coordinates of the mesh (useful to get a deformed geometry). + + as_linear: + Export quadratic surface elements as linear. + + Returns + ------- + grid: + UnstructuredGrid corresponding to the DPF Field. + """ + # Check Field location + supported_locations = [dpf.locations.nodal, dpf.locations.elemental, dpf.locations.overall] + if field.location not in supported_locations: + raise ValueError( + f"Supported field locations for translation to VTK are: {supported_locations}." + ) + + # Initialize the bare UnstructuredGrid + meshed_region = field.meshed_region + grid = dpf_mesh_to_vtk(mesh=meshed_region, nodes=nodes, as_linear=as_linear) + + # Populate with Field.data + location = field.location + if location == dpf.locations.nodal: + mesh_location = meshed_region.nodes + elif location == dpf.locations.elemental: + mesh_location = meshed_region.elements + elif location == dpf.locations.faces: + mesh_location = meshed_region.faces + if len(mesh_location) == 0: + raise ValueError("No faces found to plot on") + elif location == dpf.locations.overall: + mesh_location = meshed_region.elements + else: + raise ValueError("Only elemental, nodal or faces location are supported for plotting.") + component_count = field.component_count + if component_count > 1: + overall_data = np.full((len(mesh_location), component_count), np.nan) + else: + overall_data = np.full(len(mesh_location), np.nan) + if location != dpf.locations.overall: + ind, mask = mesh_location.map_scoping(field.scoping) + overall_data[ind] = field.data[mask] + else: + overall_data[:] = field.data[0] + + if field.location == dpf.locations.nodal: + grid.point_data[field.name] = overall_data + else: + grid.cell_data[field.name] = overall_data + return grid From 1ed82055988b3fdebf7907c2296c4bf46152dd78 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Wed, 22 May 2024 12:00:57 +0200 Subject: [PATCH 02/16] Refactor vtk_helper.py Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index 36e51910a7d..65259f51c1b 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -401,9 +401,23 @@ def dpf_field_to_vtk( # Initialize the bare UnstructuredGrid meshed_region = field.meshed_region + if meshed_region.nodes.n_nodes == 0: + raise ValueError("The field.meshed_region contains no nodes.") grid = dpf_mesh_to_vtk(mesh=meshed_region, nodes=nodes, as_linear=as_linear) - # Populate with Field.data + # Map Field.data to the VTK mesh + overall_data = _map_field_to_mesh(field=field, meshed_region=meshed_region) + + # Update the UnstructuredGrid + if field.location == dpf.locations.nodal: + grid.point_data[field.name] = overall_data + else: + grid.cell_data[field.name] = overall_data + return grid + + +def _map_field_to_mesh(field: dpf.Field, meshed_region: dpf.MeshedRegion) -> np.ndarray: + """Return an NumPy array of Field.data mapped to the mesh on the field's location.""" location = field.location if location == dpf.locations.nodal: mesh_location = meshed_region.nodes @@ -427,9 +441,4 @@ def dpf_field_to_vtk( overall_data[ind] = field.data[mask] else: overall_data[:] = field.data[0] - - if field.location == dpf.locations.nodal: - grid.point_data[field.name] = overall_data - else: - grid.cell_data[field.name] = overall_data - return grid + return overall_data From 25b5dfa5b798ba0276357080d96f9ad8c043f6e7 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Wed, 22 May 2024 12:01:09 +0200 Subject: [PATCH 03/16] Add tests Signed-off-by: paul.profizi --- tests/test_vtk_translate.py | 71 +++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 tests/test_vtk_translate.py diff --git a/tests/test_vtk_translate.py b/tests/test_vtk_translate.py new file mode 100644 index 00000000000..e46a38f51e3 --- /dev/null +++ b/tests/test_vtk_translate.py @@ -0,0 +1,71 @@ +import pytest +import ansys.dpf.core as dpf +from ansys.dpf.core import misc +from ansys.dpf.core.vtk_helper import dpf_mesh_to_vtk, dpf_field_to_vtk + +if misc.module_exists("pyvista"): + HAS_PYVISTA = True + import pyvista as pv +else: + HAS_PYVISTA = False + + +@pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") +def test_dpf_mesh_to_vtk(simple_rst): + model = dpf.Model(simple_rst) + mesh = model.metadata.meshed_region + # Mesh to VTK + ug = dpf_mesh_to_vtk(mesh=mesh) + assert isinstance(ug, pv.UnstructuredGrid) + pv.plot(ug) + # With deformation + field = model.results.displacement.on_last_time_freq().eval()[0] + initial_coord = mesh.nodes.coordinates_field + updated_coord = (initial_coord + field).eval() + ug = dpf_mesh_to_vtk(mesh=mesh, nodes=updated_coord) + assert isinstance(ug, pv.UnstructuredGrid) + pv.plot(ug) + # As linear + ug = dpf_mesh_to_vtk(mesh=mesh, as_linear=True) + assert isinstance(ug, pv.UnstructuredGrid) + pv.plot(ug) + + +@pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") +def test_dpf_field_to_vtk(simple_rst, fluent_mixing_elbow_steady_state): + model = dpf.Model(simple_rst) + mesh = model.metadata.meshed_region + field = model.results.displacement.on_last_time_freq().eval()[0] + field.name = "disp" + # Nodal Field to VTK + ug = dpf_field_to_vtk(field=field) + assert isinstance(ug, pv.UnstructuredGrid) + assert "disp" in ug.point_data.keys() + pv.plot(ug) + # With deformation + initial_coord = mesh.nodes.coordinates_field + updated_coord = (initial_coord + field).eval() + ug = dpf_field_to_vtk(field=field, nodes=updated_coord) + assert isinstance(ug, pv.UnstructuredGrid) + pv.plot(ug) + # As linear + ug = dpf_field_to_vtk(field=field, as_linear=True) + assert isinstance(ug, pv.UnstructuredGrid) + pv.plot(ug) + # Elemental Field to VTK + model = dpf.Model(fluent_mixing_elbow_steady_state()) + field = model.results.dynamic_viscosity.on_last_time_freq().eval()[0] + field.name = "DV" + ug = dpf_field_to_vtk(field=field) + assert isinstance(ug, pv.UnstructuredGrid) + assert "DV" in ug.cell_data.keys() + pv.plot(ug) + + +@pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") +def test_dpf_field_to_vtk_errors(simple_rst): + model = dpf.Model(simple_rst) + # Elemental Field to VTK + field = model.results.elemental_volume.on_last_time_freq().eval()[0] + with pytest.raises(ValueError, match="The field.meshed_region contains no nodes."): + _ = dpf_field_to_vtk(field=field) From 5be305d5a632589bdd112ee2830409a06e475415 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Wed, 22 May 2024 16:14:30 +0200 Subject: [PATCH 04/16] Add dpf_meshes_to_vtk in vtk_helper.py Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 95 ++++++++++++++++++++++++++++++++ tests/test_vtk_translate.py | 16 +++++- 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index 65259f51c1b..ee1fea64052 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -369,6 +369,39 @@ def vtk_update_coordinates(vtk_grid, coordinates_array): vtk_grid.points = copy(coordinates_array) +def dpf_meshes_to_vtk( + meshes_container: dpf.MeshesContainer, + nodes: Union[dpf.FieldsContainer, None] = None, + as_linear: bool = True +) -> pv.UnstructuredGrid: + """Return a pyvista UnstructuredGrid given a pydpf MeshedRegion. + + Parameters + ---------- + meshes_container: + MeshesContainer to export to pyVista format. + + nodes: + FieldsContainer containing the node coordinates for each mesh + (useful to get a deformed geometry). The labels must match a field to a mesh. + + as_linear : bool, optional + Export quadratic surface elements as linear. + + Returns + ------- + grid: + UnstructuredGrid corresponding to the DPF meshes. + """ + grids = [] + for i, mesh in enumerate(meshes_container): + nodes_i = None + if nodes: + nodes_i = nodes[i] + grids.append(dpf_mesh_to_vtk(mesh, nodes_i, as_linear)) + return pv.MultiBlock(grids).combine() + + def dpf_field_to_vtk( field: dpf.Field, nodes: Union[dpf.Field, None] = None, @@ -416,6 +449,68 @@ def dpf_field_to_vtk( return grid +def dpf_fieldscontainer_to_vtk( + fields_container: dpf.FieldsContainer, + nodes: Union[dpf.Field, None] = None, + as_linear: bool = True +) -> pv.UnstructuredGrid: + """Return a pyvista UnstructuredGrid given a DPF FieldsContainer. + + If the fields have different mesh supports, a global merged mesh support is created. + + Parameters + ---------- + fields_container: + FieldsContainer to export to pyVista format. + + nodes: + Field containing the node coordinates of the mesh (useful to get a deformed geometry). + + as_linear: + Export quadratic surface elements as linear. + + Returns + ------- + grid: + UnstructuredGrid corresponding to the DPF Field. + """ + # Check Field location + supported_locations = [dpf.locations.nodal, dpf.locations.elemental, dpf.locations.overall] + if fields_container[0].location not in supported_locations: + raise ValueError( + f"Supported field locations for translation to VTK are: {supported_locations}." + ) + + # Initialize the bare UnstructuredGrid + # Loop on the fields to check if merging supports is necessary + meshes = [] + for field in fields_container: + if field.meshed_region not in meshes: + meshes.append(field.meshed_region) + if len(meshes)>1: + # Merge the meshed_regions + merge_op = dpf.operators.utility.merge_meshes() + for i, mesh in enumerate(meshes): + merge_op.connect(i, mesh) + meshed_region = merge_op.eval() + else: + meshed_region = meshes[0] + if meshed_region.nodes.n_nodes == 0: + raise ValueError("The meshed_region of the fields contains no nodes.") + grid = dpf_mesh_to_vtk(mesh=meshed_region, nodes=nodes, as_linear=as_linear) + + # Map Field.data to the VTK mesh + overall_data = _map_field_to_mesh(field=field, meshed_region=meshed_region) + + # Update the UnstructuredGrid + if field.location == dpf.locations.nodal: + grid.point_data[field.name] = overall_data + else: + grid.cell_data[field.name] = overall_data + + + return grid + def _map_field_to_mesh(field: dpf.Field, meshed_region: dpf.MeshedRegion) -> np.ndarray: """Return an NumPy array of Field.data mapped to the mesh on the field's location.""" location = field.location diff --git a/tests/test_vtk_translate.py b/tests/test_vtk_translate.py index e46a38f51e3..8f71d36e7d0 100644 --- a/tests/test_vtk_translate.py +++ b/tests/test_vtk_translate.py @@ -1,7 +1,8 @@ import pytest import ansys.dpf.core as dpf from ansys.dpf.core import misc -from ansys.dpf.core.vtk_helper import dpf_mesh_to_vtk, dpf_field_to_vtk +from ansys.dpf.core.vtk_helper import \ + dpf_mesh_to_vtk, dpf_field_to_vtk, dpf_meshes_to_vtk, dpf_fieldscontainer_to_vtk if misc.module_exists("pyvista"): HAS_PYVISTA = True @@ -69,3 +70,16 @@ def test_dpf_field_to_vtk_errors(simple_rst): field = model.results.elemental_volume.on_last_time_freq().eval()[0] with pytest.raises(ValueError, match="The field.meshed_region contains no nodes."): _ = dpf_field_to_vtk(field=field) + + +@pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") +def test_dpf_meshes_to_vtk(fluent_axial_comp): + model = dpf.Model(fluent_axial_comp()) + meshes_container = dpf.operators.mesh.meshes_provider( + data_sources=model, + region_scoping=dpf.Scoping(ids=[13, 28], location=dpf.locations.zone) + ).eval() + assert len(meshes_container) == 2 + ug = dpf_meshes_to_vtk(meshes_container=meshes_container) + assert ug.GetNumberOfCells() == 13856 + pv.plot(ug) From 81a3e1ec46537924099bd4b1600872071487bf17 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Wed, 22 May 2024 16:35:36 +0200 Subject: [PATCH 05/16] Add dpf_fieldscontainer_to_vtk in vtk_helper.py Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 27 +++++++++++--------- tests/test_vtk_translate.py | 42 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index ee1fea64052..f82274856cc 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -426,7 +426,9 @@ def dpf_field_to_vtk( UnstructuredGrid corresponding to the DPF Field. """ # Check Field location - supported_locations = [dpf.locations.nodal, dpf.locations.elemental, dpf.locations.overall] + supported_locations = [ + dpf.locations.nodal, dpf.locations.elemental, dpf.locations.faces, dpf.locations.overall + ] if field.location not in supported_locations: raise ValueError( f"Supported field locations for translation to VTK are: {supported_locations}." @@ -475,7 +477,9 @@ def dpf_fieldscontainer_to_vtk( UnstructuredGrid corresponding to the DPF Field. """ # Check Field location - supported_locations = [dpf.locations.nodal, dpf.locations.elemental, dpf.locations.overall] + supported_locations = [ + dpf.locations.nodal, dpf.locations.elemental, dpf.locations.faces, dpf.locations.overall + ] if fields_container[0].location not in supported_locations: raise ValueError( f"Supported field locations for translation to VTK are: {supported_locations}." @@ -499,15 +503,16 @@ def dpf_fieldscontainer_to_vtk( raise ValueError("The meshed_region of the fields contains no nodes.") grid = dpf_mesh_to_vtk(mesh=meshed_region, nodes=nodes, as_linear=as_linear) - # Map Field.data to the VTK mesh - overall_data = _map_field_to_mesh(field=field, meshed_region=meshed_region) - - # Update the UnstructuredGrid - if field.location == dpf.locations.nodal: - grid.point_data[field.name] = overall_data - else: - grid.cell_data[field.name] = overall_data - + for i, field in enumerate(fields_container): + # Map Field.data to the VTK mesh + overall_data = _map_field_to_mesh(field=field, meshed_region=meshed_region) + label_space = fields_container.get_label_space(i) + field.name = field.name+f" {label_space}" + # Update the UnstructuredGrid + if field.location == dpf.locations.nodal: + grid.point_data[field.name] = overall_data + else: + grid.cell_data[field.name] = overall_data return grid diff --git a/tests/test_vtk_translate.py b/tests/test_vtk_translate.py index 8f71d36e7d0..21475f39ce9 100644 --- a/tests/test_vtk_translate.py +++ b/tests/test_vtk_translate.py @@ -83,3 +83,45 @@ def test_dpf_meshes_to_vtk(fluent_axial_comp): ug = dpf_meshes_to_vtk(meshes_container=meshes_container) assert ug.GetNumberOfCells() == 13856 pv.plot(ug) + + +@pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") +def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp): + model = dpf.Model(fluent_axial_comp()) + print(model) + # Elemental + fields_container = dpf.operators.result.enthalpy( + data_sources=model, + region_scoping=dpf.Scoping(ids=[13, 28], location=dpf.locations.zone), + ).eval() + assert len(fields_container) == 2 + meshes_container = dpf.operators.mesh.meshes_provider( + data_sources=model, + region_scoping=dpf.Scoping(ids=[13, 28], location=dpf.locations.zone) + ).eval() + fields_container[0].meshed_region = meshes_container[0] + fields_container[1].meshed_region = meshes_container[1] + ug = dpf_fieldscontainer_to_vtk(fields_container=fields_container) + assert ug.GetNumberOfCells() == 13856 + assert list(ug.cell_data.keys()) == ["h {'time': 1, 'zone': 13}", "h {'time': 1, 'zone': 28}"] + pv.plot(ug) + # Faces + fields_container = dpf.operators.result.wall_shear_stress( + data_sources=model, + region_scoping=dpf.Scoping(ids=[3, 4, 7], location=dpf.locations.zone), + ).eval() + assert len(fields_container) == 3 + meshes_container = dpf.operators.mesh.meshes_provider( + data_sources=model, + region_scoping=dpf.Scoping(ids=[3, 4, 7], location=dpf.locations.zone) + ).eval() + fields_container[0].meshed_region = meshes_container[0] + fields_container[1].meshed_region = meshes_container[1] + fields_container[2].meshed_region = meshes_container[2] + ug = dpf_fieldscontainer_to_vtk(fields_container=fields_container) + assert ug.GetNumberOfCells() == 1144 + assert list(ug.cell_data.keys()) == [ + "tau_w {'time': 1, 'zone': 3}", + "tau_w {'time': 1, 'zone': 4}", + "tau_w {'time': 1, 'zone': 7}"] + pv.plot(ug) From bd6bb3a1e81269a6beb79df3efc5e3e85f3bbf97 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Wed, 22 May 2024 18:11:46 +0200 Subject: [PATCH 06/16] Add retro criterion on tests Signed-off-by: paul.profizi --- tests/test_vtk_translate.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/test_vtk_translate.py b/tests/test_vtk_translate.py index 21475f39ce9..6541d9e32fa 100644 --- a/tests/test_vtk_translate.py +++ b/tests/test_vtk_translate.py @@ -1,4 +1,5 @@ import pytest +import conftest import ansys.dpf.core as dpf from ansys.dpf.core import misc from ansys.dpf.core.vtk_helper import \ @@ -32,6 +33,10 @@ def test_dpf_mesh_to_vtk(simple_rst): pv.plot(ug) +@pytest.mark.skipif( + not conftest.SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_0, + reason="CFF source operators where not supported before 7.0,", +) @pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") def test_dpf_field_to_vtk(simple_rst, fluent_mixing_elbow_steady_state): model = dpf.Model(simple_rst) @@ -72,6 +77,10 @@ def test_dpf_field_to_vtk_errors(simple_rst): _ = dpf_field_to_vtk(field=field) +@pytest.mark.skipif( + not conftest.SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_0, + reason="CFF source operators where not supported before 7.0,", +) @pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") def test_dpf_meshes_to_vtk(fluent_axial_comp): model = dpf.Model(fluent_axial_comp()) @@ -85,6 +94,10 @@ def test_dpf_meshes_to_vtk(fluent_axial_comp): pv.plot(ug) +@pytest.mark.skipif( + not conftest.SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_0, + reason="CFF source operators where not supported before 7.0,", +) @pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp): model = dpf.Model(fluent_axial_comp()) @@ -103,7 +116,8 @@ def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp): fields_container[1].meshed_region = meshes_container[1] ug = dpf_fieldscontainer_to_vtk(fields_container=fields_container) assert ug.GetNumberOfCells() == 13856 - assert list(ug.cell_data.keys()) == ["h {'time': 1, 'zone': 13}", "h {'time': 1, 'zone': 28}"] + assert sorted(list(ug.cell_data.keys())) == ["h {'time': 1, 'zone': 13}", + "h {'time': 1, 'zone': 28}"] pv.plot(ug) # Faces fields_container = dpf.operators.result.wall_shear_stress( @@ -120,7 +134,7 @@ def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp): fields_container[2].meshed_region = meshes_container[2] ug = dpf_fieldscontainer_to_vtk(fields_container=fields_container) assert ug.GetNumberOfCells() == 1144 - assert list(ug.cell_data.keys()) == [ + assert sorted(list(ug.cell_data.keys())) == [ "tau_w {'time': 1, 'zone': 3}", "tau_w {'time': 1, 'zone': 4}", "tau_w {'time': 1, 'zone': 7}"] From bcae349e987a223e7b2ebb7154e01610907f2607 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Wed, 22 May 2024 18:24:19 +0200 Subject: [PATCH 07/16] Sort field naming by label_space Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index f82274856cc..e93a2385ce2 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -507,7 +507,7 @@ def dpf_fieldscontainer_to_vtk( # Map Field.data to the VTK mesh overall_data = _map_field_to_mesh(field=field, meshed_region=meshed_region) label_space = fields_container.get_label_space(i) - field.name = field.name+f" {label_space}" + field.name = field.name+f" {dict(sorted(list(label_space)))}" # Update the UnstructuredGrid if field.location == dpf.locations.nodal: grid.point_data[field.name] = overall_data From 21a26ca0c96a5b4208dd4fc0e14975c23e47a64f Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Wed, 22 May 2024 18:35:51 +0200 Subject: [PATCH 08/16] Sort field naming by label_space Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index e93a2385ce2..7a460220094 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -507,7 +507,8 @@ def dpf_fieldscontainer_to_vtk( # Map Field.data to the VTK mesh overall_data = _map_field_to_mesh(field=field, meshed_region=meshed_region) label_space = fields_container.get_label_space(i) - field.name = field.name+f" {dict(sorted(list(label_space)))}" + label_space = dict([(k, label_space[k]) for k in sorted(label_space.keys())]) + field.name = field.name+f" {label_space}" # Update the UnstructuredGrid if field.location == dpf.locations.nodal: grid.point_data[field.name] = overall_data From 00aae7d834ec777481aa954fd33339d584910a5f Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Fri, 24 May 2024 10:35:05 +0200 Subject: [PATCH 09/16] Add optional mesh arguments to fields translation methods Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 22 ++++++++++++++++++++++ tests/test_vtk_translate.py | 15 +++++++-------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index 7a460220094..f920456a5b9 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -404,6 +404,7 @@ def dpf_meshes_to_vtk( def dpf_field_to_vtk( field: dpf.Field, + meshed_region: Union[dpf.MeshedRegion, None] = None, nodes: Union[dpf.Field, None] = None, as_linear: bool = True ) -> pv.UnstructuredGrid: @@ -414,6 +415,10 @@ def dpf_field_to_vtk( field: Field to export to pyVista format. + meshed_region: + Mesh to associate to the field. + Useful for fluid results where the field is not automatically associated to its mesh. + nodes: Field containing the node coordinates of the mesh (useful to get a deformed geometry). @@ -434,6 +439,10 @@ def dpf_field_to_vtk( f"Supported field locations for translation to VTK are: {supported_locations}." ) + # Associate the provided mesh with the field + if meshed_region: + field.meshed_region = meshed_region + # Initialize the bare UnstructuredGrid meshed_region = field.meshed_region if meshed_region.nodes.n_nodes == 0: @@ -453,6 +462,7 @@ def dpf_field_to_vtk( def dpf_fieldscontainer_to_vtk( fields_container: dpf.FieldsContainer, + meshes_container: Union[dpf.MeshesContainer, None] = None, nodes: Union[dpf.Field, None] = None, as_linear: bool = True ) -> pv.UnstructuredGrid: @@ -465,6 +475,10 @@ def dpf_fieldscontainer_to_vtk( fields_container: FieldsContainer to export to pyVista format. + meshes_container: + MeshesContainer with meshes to associate to the fields in the FieldsContainer. + Useful for fluid results where the fields are not automatically associated to their mesh. + nodes: Field containing the node coordinates of the mesh (useful to get a deformed geometry). @@ -485,6 +499,14 @@ def dpf_fieldscontainer_to_vtk( f"Supported field locations for translation to VTK are: {supported_locations}." ) + # Associate the meshes in meshes_container to the corresponding fields if provided + if meshes_container: + for i, mesh in enumerate(meshes_container): + label_space = meshes_container.get_label_space(i) + fields_container.get_field( + label_space_or_index=label_space + ).meshed_region = meshes_container.get_mesh(label_space_or_index=label_space) + # Initialize the bare UnstructuredGrid # Loop on the fields to check if merging supports is necessary meshes = [] diff --git a/tests/test_vtk_translate.py b/tests/test_vtk_translate.py index 6541d9e32fa..f27defd14ea 100644 --- a/tests/test_vtk_translate.py +++ b/tests/test_vtk_translate.py @@ -62,7 +62,7 @@ def test_dpf_field_to_vtk(simple_rst, fluent_mixing_elbow_steady_state): model = dpf.Model(fluent_mixing_elbow_steady_state()) field = model.results.dynamic_viscosity.on_last_time_freq().eval()[0] field.name = "DV" - ug = dpf_field_to_vtk(field=field) + ug = dpf_field_to_vtk(field=field, meshed_region=model.metadata.meshed_region) assert isinstance(ug, pv.UnstructuredGrid) assert "DV" in ug.cell_data.keys() pv.plot(ug) @@ -112,9 +112,9 @@ def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp): data_sources=model, region_scoping=dpf.Scoping(ids=[13, 28], location=dpf.locations.zone) ).eval() - fields_container[0].meshed_region = meshes_container[0] - fields_container[1].meshed_region = meshes_container[1] - ug = dpf_fieldscontainer_to_vtk(fields_container=fields_container) + ug = dpf_fieldscontainer_to_vtk( + fields_container=fields_container, meshes_container=meshes_container + ) assert ug.GetNumberOfCells() == 13856 assert sorted(list(ug.cell_data.keys())) == ["h {'time': 1, 'zone': 13}", "h {'time': 1, 'zone': 28}"] @@ -129,10 +129,9 @@ def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp): data_sources=model, region_scoping=dpf.Scoping(ids=[3, 4, 7], location=dpf.locations.zone) ).eval() - fields_container[0].meshed_region = meshes_container[0] - fields_container[1].meshed_region = meshes_container[1] - fields_container[2].meshed_region = meshes_container[2] - ug = dpf_fieldscontainer_to_vtk(fields_container=fields_container) + ug = dpf_fieldscontainer_to_vtk( + fields_container=fields_container, meshes_container=meshes_container + ) assert ug.GetNumberOfCells() == 1144 assert sorted(list(ug.cell_data.keys())) == [ "tau_w {'time': 1, 'zone': 3}", From 70200e47aee9b761e768b72ffa95516469d568c2 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Mon, 27 May 2024 11:42:05 +0200 Subject: [PATCH 10/16] Fix for Docker and test on all server types Signed-off-by: paul.profizi --- tests/test_vtk_translate.py | 45 +++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/tests/test_vtk_translate.py b/tests/test_vtk_translate.py index f27defd14ea..19515160c4e 100644 --- a/tests/test_vtk_translate.py +++ b/tests/test_vtk_translate.py @@ -13,8 +13,8 @@ @pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") -def test_dpf_mesh_to_vtk(simple_rst): - model = dpf.Model(simple_rst) +def test_dpf_mesh_to_vtk(simple_rst, server_type): + model = dpf.Model(simple_rst, server=server_type) mesh = model.metadata.meshed_region # Mesh to VTK ug = dpf_mesh_to_vtk(mesh=mesh) @@ -38,8 +38,8 @@ def test_dpf_mesh_to_vtk(simple_rst): reason="CFF source operators where not supported before 7.0,", ) @pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") -def test_dpf_field_to_vtk(simple_rst, fluent_mixing_elbow_steady_state): - model = dpf.Model(simple_rst) +def test_dpf_field_to_vtk(simple_rst, fluent_mixing_elbow_steady_state, server_type): + model = dpf.Model(simple_rst, server=server_type) mesh = model.metadata.meshed_region field = model.results.displacement.on_last_time_freq().eval()[0] field.name = "disp" @@ -59,7 +59,7 @@ def test_dpf_field_to_vtk(simple_rst, fluent_mixing_elbow_steady_state): assert isinstance(ug, pv.UnstructuredGrid) pv.plot(ug) # Elemental Field to VTK - model = dpf.Model(fluent_mixing_elbow_steady_state()) + model = dpf.Model(fluent_mixing_elbow_steady_state(), server=server_type) field = model.results.dynamic_viscosity.on_last_time_freq().eval()[0] field.name = "DV" ug = dpf_field_to_vtk(field=field, meshed_region=model.metadata.meshed_region) @@ -69,11 +69,15 @@ def test_dpf_field_to_vtk(simple_rst, fluent_mixing_elbow_steady_state): @pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") -def test_dpf_field_to_vtk_errors(simple_rst): - model = dpf.Model(simple_rst) +def test_dpf_field_to_vtk_errors(simple_rst, server_type): + model = dpf.Model(simple_rst, server=server_type) # Elemental Field to VTK field = model.results.elemental_volume.on_last_time_freq().eval()[0] - with pytest.raises(ValueError, match="The field.meshed_region contains no nodes."): + if server_type.on_docker: + match_str = "the field doesn't have this support type" + else: + match_str = "The field.meshed_region contains no nodes." + with pytest.raises(ValueError, match=match_str): _ = dpf_field_to_vtk(field=field) @@ -82,11 +86,12 @@ def test_dpf_field_to_vtk_errors(simple_rst): reason="CFF source operators where not supported before 7.0,", ) @pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") -def test_dpf_meshes_to_vtk(fluent_axial_comp): - model = dpf.Model(fluent_axial_comp()) +def test_dpf_meshes_to_vtk(fluent_axial_comp, server_type): + model = dpf.Model(fluent_axial_comp(), server=server_type) meshes_container = dpf.operators.mesh.meshes_provider( data_sources=model, - region_scoping=dpf.Scoping(ids=[13, 28], location=dpf.locations.zone) + server=server_type, + region_scoping=dpf.Scoping(ids=[13, 28], location=dpf.locations.zone, server=server_type) ).eval() assert len(meshes_container) == 2 ug = dpf_meshes_to_vtk(meshes_container=meshes_container) @@ -99,18 +104,21 @@ def test_dpf_meshes_to_vtk(fluent_axial_comp): reason="CFF source operators where not supported before 7.0,", ) @pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") -def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp): - model = dpf.Model(fluent_axial_comp()) +def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp, server_type): + model = dpf.Model(fluent_axial_comp(), server=server_type) print(model) + zone_scoping = dpf.Scoping(ids=[13, 28], location=dpf.locations.zone, server=server_type) # Elemental fields_container = dpf.operators.result.enthalpy( data_sources=model, - region_scoping=dpf.Scoping(ids=[13, 28], location=dpf.locations.zone), + server=server_type, + region_scoping=zone_scoping, ).eval() assert len(fields_container) == 2 meshes_container = dpf.operators.mesh.meshes_provider( data_sources=model, - region_scoping=dpf.Scoping(ids=[13, 28], location=dpf.locations.zone) + server=server_type, + region_scoping=zone_scoping ).eval() ug = dpf_fieldscontainer_to_vtk( fields_container=fields_container, meshes_container=meshes_container @@ -119,15 +127,18 @@ def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp): assert sorted(list(ug.cell_data.keys())) == ["h {'time': 1, 'zone': 13}", "h {'time': 1, 'zone': 28}"] pv.plot(ug) + zone_scoping = dpf.Scoping(ids=[3, 4, 7], location=dpf.locations.zone, server=server_type) # Faces fields_container = dpf.operators.result.wall_shear_stress( data_sources=model, - region_scoping=dpf.Scoping(ids=[3, 4, 7], location=dpf.locations.zone), + server=server_type, + region_scoping=zone_scoping, ).eval() assert len(fields_container) == 3 meshes_container = dpf.operators.mesh.meshes_provider( data_sources=model, - region_scoping=dpf.Scoping(ids=[3, 4, 7], location=dpf.locations.zone) + server=server_type, + region_scoping=zone_scoping ).eval() ug = dpf_fieldscontainer_to_vtk( fields_container=fields_container, meshes_container=meshes_container From 96de2c3cb5f4d4c2db0050049e7d444122a43554 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Mon, 27 May 2024 14:51:16 +0200 Subject: [PATCH 11/16] Fix error logic when field has no mesh Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 16 ++++++++++++++-- tests/test_vtk_translate.py | 6 +----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index f920456a5b9..18c3c79790c 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -442,11 +442,23 @@ def dpf_field_to_vtk( # Associate the provided mesh with the field if meshed_region: field.meshed_region = meshed_region + else: + try: + meshed_region = field.meshed_region + except errors.DPFServerException as e: + if "the field doesn't have this support type" in str(e): + raise ValueError("The field does not have a meshed_region.") + else: + raise e + except RuntimeError as e: + if "The field's support is not a mesh" in str(e): + raise ValueError("The field does not have a meshed_region.") + else: + raise e # Initialize the bare UnstructuredGrid - meshed_region = field.meshed_region if meshed_region.nodes.n_nodes == 0: - raise ValueError("The field.meshed_region contains no nodes.") + raise ValueError("The field does not have a meshed_region.") grid = dpf_mesh_to_vtk(mesh=meshed_region, nodes=nodes, as_linear=as_linear) # Map Field.data to the VTK mesh diff --git a/tests/test_vtk_translate.py b/tests/test_vtk_translate.py index 19515160c4e..25ead6216ac 100644 --- a/tests/test_vtk_translate.py +++ b/tests/test_vtk_translate.py @@ -73,11 +73,7 @@ def test_dpf_field_to_vtk_errors(simple_rst, server_type): model = dpf.Model(simple_rst, server=server_type) # Elemental Field to VTK field = model.results.elemental_volume.on_last_time_freq().eval()[0] - if server_type.on_docker: - match_str = "the field doesn't have this support type" - else: - match_str = "The field.meshed_region contains no nodes." - with pytest.raises(ValueError, match=match_str): + with pytest.raises(ValueError, match="The field does not have a meshed_region."): _ = dpf_field_to_vtk(field=field) From 41ab8e6341852492d101f239f9aa6bba89014d55 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Mon, 27 May 2024 15:38:04 +0200 Subject: [PATCH 12/16] Fix test for ansys-grpc-dpf Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 2 +- tests/test_vtk_translate.py | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index 18c3c79790c..518e490e568 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -527,7 +527,7 @@ def dpf_fieldscontainer_to_vtk( meshes.append(field.meshed_region) if len(meshes)>1: # Merge the meshed_regions - merge_op = dpf.operators.utility.merge_meshes() + merge_op = dpf.operators.utility.merge_meshes(server=fields_container._server) for i, mesh in enumerate(meshes): merge_op.connect(i, mesh) meshed_region = merge_op.eval() diff --git a/tests/test_vtk_translate.py b/tests/test_vtk_translate.py index 25ead6216ac..5200d09e975 100644 --- a/tests/test_vtk_translate.py +++ b/tests/test_vtk_translate.py @@ -59,7 +59,7 @@ def test_dpf_field_to_vtk(simple_rst, fluent_mixing_elbow_steady_state, server_t assert isinstance(ug, pv.UnstructuredGrid) pv.plot(ug) # Elemental Field to VTK - model = dpf.Model(fluent_mixing_elbow_steady_state(), server=server_type) + model = dpf.Model(fluent_mixing_elbow_steady_state(server=server_type), server=server_type) field = model.results.dynamic_viscosity.on_last_time_freq().eval()[0] field.name = "DV" ug = dpf_field_to_vtk(field=field, meshed_region=model.metadata.meshed_region) @@ -83,7 +83,7 @@ def test_dpf_field_to_vtk_errors(simple_rst, server_type): ) @pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") def test_dpf_meshes_to_vtk(fluent_axial_comp, server_type): - model = dpf.Model(fluent_axial_comp(), server=server_type) + model = dpf.Model(fluent_axial_comp(server=server_type), server=server_type) meshes_container = dpf.operators.mesh.meshes_provider( data_sources=model, server=server_type, @@ -101,8 +101,7 @@ def test_dpf_meshes_to_vtk(fluent_axial_comp, server_type): ) @pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp, server_type): - model = dpf.Model(fluent_axial_comp(), server=server_type) - print(model) + model = dpf.Model(fluent_axial_comp(server=server_type), server=server_type) zone_scoping = dpf.Scoping(ids=[13, 28], location=dpf.locations.zone, server=server_type) # Elemental fields_container = dpf.operators.result.enthalpy( @@ -114,7 +113,7 @@ def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp, server_type): meshes_container = dpf.operators.mesh.meshes_provider( data_sources=model, server=server_type, - region_scoping=zone_scoping + region_scoping=zone_scoping, ).eval() ug = dpf_fieldscontainer_to_vtk( fields_container=fields_container, meshes_container=meshes_container From d9bf4268148dddb2e9155ea28c2104d992777152 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Tue, 28 May 2024 16:15:04 +0200 Subject: [PATCH 13/16] Add dpf_property_field_to_vtk Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 52 ++++++++++++++++++++++++++++++++ tests/test_vtk_translate.py | 17 ++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index 518e490e568..4bb221a4131 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -577,3 +577,55 @@ def _map_field_to_mesh(field: dpf.Field, meshed_region: dpf.MeshedRegion) -> np. else: overall_data[:] = field.data[0] return overall_data + + +def dpf_property_field_to_vtk( + property_field: dpf.PropertyField, + meshed_region: dpf.MeshedRegion, + nodes: Union[dpf.Field, None] = None, + as_linear: bool = True +) -> pv.UnstructuredGrid: + """Return a pyvista UnstructuredGrid given a DPF PropertyField. + + Parameters + ---------- + property_field: + PropertyField to export to pyVista format. + + meshed_region: + Mesh to associate to the property field. + + nodes: + Field containing the node coordinates of the mesh (useful to get a deformed geometry). + + as_linear: + Export quadratic surface elements as linear. + + Returns + ------- + grid: + UnstructuredGrid corresponding to the DPF PropertyField. + """ + # Check Field location + supported_locations = [ + dpf.locations.nodal, dpf.locations.elemental, dpf.locations.faces, dpf.locations.overall + ] + if property_field.location not in supported_locations: + raise ValueError( + f"Supported field locations for translation to VTK are: {supported_locations}." + ) + + # Initialize the bare UnstructuredGrid + if meshed_region.nodes.n_nodes == 0: + raise ValueError("The property field does not have a meshed_region.") + grid = dpf_mesh_to_vtk(mesh=meshed_region, nodes=nodes, as_linear=as_linear) + + # Map Field.data to the VTK mesh + overall_data = _map_field_to_mesh(field=property_field, meshed_region=meshed_region) + + # Update the UnstructuredGrid + if property_field.location == dpf.locations.nodal: + grid.point_data[property_field.name] = overall_data + else: + grid.cell_data[property_field.name] = overall_data + return grid diff --git a/tests/test_vtk_translate.py b/tests/test_vtk_translate.py index 5200d09e975..46d7e2450cf 100644 --- a/tests/test_vtk_translate.py +++ b/tests/test_vtk_translate.py @@ -3,7 +3,8 @@ import ansys.dpf.core as dpf from ansys.dpf.core import misc from ansys.dpf.core.vtk_helper import \ - dpf_mesh_to_vtk, dpf_field_to_vtk, dpf_meshes_to_vtk, dpf_fieldscontainer_to_vtk + dpf_mesh_to_vtk, dpf_field_to_vtk, dpf_meshes_to_vtk, \ + dpf_fieldscontainer_to_vtk, dpf_property_field_to_vtk if misc.module_exists("pyvista"): HAS_PYVISTA = True @@ -144,3 +145,17 @@ def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp, server_type): "tau_w {'time': 1, 'zone': 4}", "tau_w {'time': 1, 'zone': 7}"] pv.plot(ug) + + +@pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") +def test_dpf_field_to_vtk(simple_rst, server_type): + model = dpf.Model(simple_rst, server=server_type) + mesh = model.metadata.meshed_region + property_field = mesh.property_field(property_name="mat") + print(property_field) + property_field.name = "mat_id" + # PropertyField to VTK + ug = dpf_property_field_to_vtk(property_field=property_field, meshed_region=mesh) + assert isinstance(ug, pv.UnstructuredGrid) + assert "mat_id" in ug.cell_data.keys() + pv.plot(ug) From b12dc9189e5a63f356a929f7a46b132e547b1b5e Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Wed, 29 May 2024 10:35:40 +0200 Subject: [PATCH 14/16] Fix retro-compatibility Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 4 ++++ tests/test_vtk_translate.py | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index 4bb221a4131..48edefe82d7 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -579,6 +579,7 @@ def _map_field_to_mesh(field: dpf.Field, meshed_region: dpf.MeshedRegion) -> np. return overall_data +@version_requires("8.1") def dpf_property_field_to_vtk( property_field: dpf.PropertyField, meshed_region: dpf.MeshedRegion, @@ -587,6 +588,9 @@ def dpf_property_field_to_vtk( ) -> pv.UnstructuredGrid: """Return a pyvista UnstructuredGrid given a DPF PropertyField. + ..note: + Available starting with DPF 2024.2.pre1. + Parameters ---------- property_field: diff --git a/tests/test_vtk_translate.py b/tests/test_vtk_translate.py index 46d7e2450cf..3411c7d9284 100644 --- a/tests/test_vtk_translate.py +++ b/tests/test_vtk_translate.py @@ -147,8 +147,12 @@ def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp, server_type): pv.plot(ug) +@pytest.mark.skipif( + not conftest.SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_8_1, + reason="Could not set a PropertyField name before 8.1,", +) @pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") -def test_dpf_field_to_vtk(simple_rst, server_type): +def test_dpf_property_field_to_vtk(simple_rst, server_type): model = dpf.Model(simple_rst, server=server_type) mesh = model.metadata.meshed_region property_field = mesh.property_field(property_name="mat") From 08562ea604908837d1ab70c440690b3f2b902a94 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Fri, 31 May 2024 16:29:54 +0200 Subject: [PATCH 15/16] Fix version_requires undefined Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index 48edefe82d7..d6e67db2e39 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -1,8 +1,6 @@ import numpy as np import pyvista as pv from typing import Union -import ansys.dpf.core as dpf -from ansys.dpf.core import errors from vtk import ( VTK_HEXAHEDRON, VTK_LINE, @@ -23,6 +21,10 @@ VTK_WEDGE, vtkVersion, ) + +import ansys.dpf.core as dpf +from ansys.dpf.core import errors +from ansys.dpf.core.check_version import version_requires from ansys.dpf.core.elements import element_types VTK9 = vtkVersion().GetVTKMajorVersion() >= 9 From 5e5fc3bc4a60bf74bf44c2f5c9339d737b00d9ab Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Fri, 31 May 2024 18:06:57 +0200 Subject: [PATCH 16/16] Fix requirement on server version for dpf_property_field_to_vtk Signed-off-by: paul.profizi --- src/ansys/dpf/core/vtk_helper.py | 16 ++++++++++++---- tests/test_vtk_translate.py | 7 ++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index d6e67db2e39..d4dff217f05 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -24,7 +24,7 @@ import ansys.dpf.core as dpf from ansys.dpf.core import errors -from ansys.dpf.core.check_version import version_requires +from ansys.dpf.core.check_version import server_meet_version_and_raise from ansys.dpf.core.elements import element_types VTK9 = vtkVersion().GetVTKMajorVersion() >= 9 @@ -553,8 +553,12 @@ def dpf_fieldscontainer_to_vtk( return grid -def _map_field_to_mesh(field: dpf.Field, meshed_region: dpf.MeshedRegion) -> np.ndarray: - """Return an NumPy array of Field.data mapped to the mesh on the field's location.""" + +def _map_field_to_mesh( + field: Union[dpf.Field, dpf.PropertyField], + meshed_region: dpf.MeshedRegion +) -> np.ndarray: + """Return an NumPy array of 'Field.data' mapped to the mesh on the field's location.""" location = field.location if location == dpf.locations.nodal: mesh_location = meshed_region.nodes @@ -581,7 +585,6 @@ def _map_field_to_mesh(field: dpf.Field, meshed_region: dpf.MeshedRegion) -> np. return overall_data -@version_requires("8.1") def dpf_property_field_to_vtk( property_field: dpf.PropertyField, meshed_region: dpf.MeshedRegion, @@ -612,6 +615,11 @@ def dpf_property_field_to_vtk( grid: UnstructuredGrid corresponding to the DPF PropertyField. """ + server_meet_version_and_raise( + required_version="8.1", + server=meshed_region._server, + msg="Use of dpf_property_field_to_vtk requires DPF 2024.2.pre1 or above." + ) # Check Field location supported_locations = [ dpf.locations.nodal, dpf.locations.elemental, dpf.locations.faces, dpf.locations.overall diff --git a/tests/test_vtk_translate.py b/tests/test_vtk_translate.py index 3411c7d9284..0de8a6cee6a 100644 --- a/tests/test_vtk_translate.py +++ b/tests/test_vtk_translate.py @@ -1,7 +1,7 @@ import pytest import conftest import ansys.dpf.core as dpf -from ansys.dpf.core import misc +from ansys.dpf.core import errors, misc from ansys.dpf.core.vtk_helper import \ dpf_mesh_to_vtk, dpf_field_to_vtk, dpf_meshes_to_vtk, \ dpf_fieldscontainer_to_vtk, dpf_property_field_to_vtk @@ -147,10 +147,7 @@ def test_dpf_fieldscontainer_to_vtk(fluent_axial_comp, server_type): pv.plot(ug) -@pytest.mark.skipif( - not conftest.SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_8_1, - reason="Could not set a PropertyField name before 8.1,", -) +@pytest.mark.xfail(raises=errors.DpfVersionNotSupported) @pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") def test_dpf_property_field_to_vtk(simple_rst, server_type): model = dpf.Model(simple_rst, server=server_type)