diff --git a/src/ansys/dpf/core/vtk_helper.py b/src/ansys/dpf/core/vtk_helper.py index d4dff217f0..d70a13a4ea 100644 --- a/src/ansys/dpf/core/vtk_helper.py +++ b/src/ansys/dpf/core/vtk_helper.py @@ -339,21 +339,24 @@ def compute_offset(): def dpf_mesh_to_vtk( mesh: dpf.MeshedRegion, nodes: Union[dpf.Field, None] = None, - as_linear: bool = True + as_linear: bool = True, ) -> pv.UnstructuredGrid: """Return a pyvista UnstructuredGrid given a pydpf MeshedRegion. Parameters ---------- - mesh : dpf.MeshedRegion + mesh: Meshed Region to export to pyVista format. - nodes : dpf.Field, optional + nodes: Field containing the node coordinates of the mesh (useful to get a deformed geometry). - as_linear : bool, optional + as_linear: Export quadratic surface elements as linear. + export_faces: + Whether to export face elements along with volume elements for fluid meshes. + Returns ------- grid: @@ -408,7 +411,8 @@ 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 + as_linear: bool = True, + field_name : str = "", ) -> pv.UnstructuredGrid: """Return a pyvista UnstructuredGrid given a DPF Field. @@ -427,6 +431,9 @@ def dpf_field_to_vtk( as_linear: Export quadratic surface elements as linear. + field_name: + Oberride the default field name with this. + Returns ------- grid: @@ -457,20 +464,15 @@ def dpf_field_to_vtk( raise ValueError("The field does not have a meshed_region.") else: raise e - # Initialize the bare UnstructuredGrid if meshed_region.nodes.n_nodes == 0: 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 - 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 + grid = append_field_to_grid( + field=field, meshed_region=meshed_region, grid=grid, field_name=field_name + ) + return grid @@ -478,7 +480,8 @@ 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 + as_linear: bool = True, + field_name: str = "", ) -> pv.UnstructuredGrid: """Return a pyvista UnstructuredGrid given a DPF FieldsContainer. @@ -499,6 +502,9 @@ def dpf_fieldscontainer_to_vtk( as_linear: Export quadratic surface elements as linear. + field_name: + Oberride the default field name with this. + Returns ------- grid: @@ -527,7 +533,7 @@ def dpf_fieldscontainer_to_vtk( for field in fields_container: if field.meshed_region not in meshes: meshes.append(field.meshed_region) - if len(meshes)>1: + if len(meshes) > 1: # Merge the meshed_regions merge_op = dpf.operators.utility.merge_meshes(server=fields_container._server) for i, mesh in enumerate(meshes): @@ -538,19 +544,10 @@ def dpf_fieldscontainer_to_vtk( 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) - - 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) - 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 - else: - grid.cell_data[field.name] = overall_data - + grid = append_fieldscontainer_to_grid( + fields_container=fields_container, meshed_region=meshed_region, grid=grid, + field_name=field_name + ) return grid @@ -589,7 +586,8 @@ def dpf_property_field_to_vtk( property_field: dpf.PropertyField, meshed_region: dpf.MeshedRegion, nodes: Union[dpf.Field, None] = None, - as_linear: bool = True + as_linear: bool = True, + field_name: str = "", ) -> pv.UnstructuredGrid: """Return a pyvista UnstructuredGrid given a DPF PropertyField. @@ -610,6 +608,9 @@ def dpf_property_field_to_vtk( as_linear: Export quadratic surface elements as linear. + field_name: + Oberride the default field name with this. + Returns ------- grid: @@ -633,13 +634,47 @@ def dpf_property_field_to_vtk( 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) + + grid = append_field_to_grid( + field=property_field, meshed_region=meshed_region, grid=grid, field_name=field_name + ) + + return grid - # Map Field.data to the VTK mesh - overall_data = _map_field_to_mesh(field=property_field, meshed_region=meshed_region) +def append_field_to_grid( + field: Union[dpf.Field, dpf.PropertyField], + meshed_region: dpf.MeshedRegion, + grid: pv.UnstructuredGrid, + field_name: str = "", +) -> pv.UnstructuredGrid: + """Append field data to a VTK UnstructuredGrid based on a MeshedRegion.""" + # Map Field.data to the VTK mesh + overall_data = _map_field_to_mesh(field=field, meshed_region=meshed_region) + if not field_name: + field_name = field.name # Update the UnstructuredGrid - if property_field.location == dpf.locations.nodal: - grid.point_data[property_field.name] = overall_data + if field.location == dpf.locations.nodal: + grid.point_data[field_name] = overall_data else: - grid.cell_data[property_field.name] = overall_data + grid.cell_data[field_name] = overall_data + return grid + + +def append_fieldscontainer_to_grid( + fields_container: dpf.FieldsContainer, + meshed_region: dpf.MeshedRegion, + grid: pv.UnstructuredGrid, + field_name: str = "", +) -> pv.UnstructuredGrid: + """Append fields data to a VTK UnstructuredGrid based on a MeshedRegion.""" + for i, field in enumerate(fields_container): + label_space = fields_container.get_label_space(i) + label_space = dict([(k, label_space[k]) for k in sorted(label_space.keys())]) + if not field_name: + field_name = field.name + grid = append_field_to_grid( + field=field, meshed_region=meshed_region, grid=grid, + field_name=field_name+f" {label_space}" + ) return grid diff --git a/tests/test_vtk_translate.py b/tests/test_vtk_translate.py index 0de8a6cee6..b08b6672f7 100644 --- a/tests/test_vtk_translate.py +++ b/tests/test_vtk_translate.py @@ -4,7 +4,8 @@ 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 + dpf_fieldscontainer_to_vtk, dpf_property_field_to_vtk, \ + append_field_to_grid, append_fieldscontainer_to_grid if misc.module_exists("pyvista"): HAS_PYVISTA = True @@ -43,9 +44,8 @@ def test_dpf_field_to_vtk(simple_rst, fluent_mixing_elbow_steady_state, server_t 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" # Nodal Field to VTK - ug = dpf_field_to_vtk(field=field) + ug = dpf_field_to_vtk(field=field, field_name="disp") assert isinstance(ug, pv.UnstructuredGrid) assert "disp" in ug.point_data.keys() pv.plot(ug) @@ -62,8 +62,9 @@ def test_dpf_field_to_vtk(simple_rst, fluent_mixing_elbow_steady_state, server_t # Elemental Field to VTK 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) + ug = dpf_field_to_vtk( + field=field, meshed_region=model.metadata.meshed_region, field_name="DV" + ) assert isinstance(ug, pv.UnstructuredGrid) assert "DV" in ug.cell_data.keys() pv.plot(ug) @@ -154,9 +155,48 @@ def test_dpf_property_field_to_vtk(simple_rst, 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) + ug = dpf_property_field_to_vtk( + property_field=property_field, meshed_region=mesh, field_name="mat_id" + ) assert isinstance(ug, pv.UnstructuredGrid) assert "mat_id" in ug.cell_data.keys() pv.plot(ug) + + +@pytest.mark.xfail(raises=errors.DpfVersionNotSupported) +@pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") +def test_append_field_to_grid(simple_rst, 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] + # Nodal Field to VTK + ug = dpf_field_to_vtk(field=field, field_name="disp") + assert isinstance(ug, pv.UnstructuredGrid) + assert "disp" in ug.point_data.keys() + # Append Elemental Field + field = model.results.elemental_volume.on_last_time_freq().eval()[0] + ug = append_field_to_grid(field=field, meshed_region=mesh, grid=ug, field_name="volume") + assert isinstance(ug, pv.UnstructuredGrid) + assert "disp" in ug.point_data.keys() + assert "volume" in ug.cell_data.keys() + + +@pytest.mark.xfail(raises=errors.DpfVersionNotSupported) +@pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista") +def test_append_fields_container_to_grid(simple_rst, server_type): + model = dpf.Model(simple_rst, server=server_type) + mesh = model.metadata.meshed_region + fc = model.results.displacement.eval() + # Nodal Field to VTK + ug = dpf_fieldscontainer_to_vtk(fields_container=fc, field_name="disp") + assert isinstance(ug, pv.UnstructuredGrid) + assert "disp {'time': 1}" in ug.point_data.keys() + # Append Elemental Field + fc = model.results.elemental_volume.eval() + ug = append_fieldscontainer_to_grid( + fields_container=fc, meshed_region=mesh, grid=ug, field_name="volume" + ) + assert isinstance(ug, pv.UnstructuredGrid) + assert "disp {'time': 1}" in ug.point_data.keys() + assert "volume {'time': 1}" in ug.cell_data.keys()