From 22fe927d8842d70b681d90c21066e31a2130ad8f Mon Sep 17 00:00:00 2001 From: Mainak Kundu Date: Fri, 21 Jun 2024 21:25:54 -0400 Subject: [PATCH 1/2] feat: Display solution variables data --- .../pyvista/solution_variables.py | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/ansys/fluent/visualization/pyvista/solution_variables.py diff --git a/src/ansys/fluent/visualization/pyvista/solution_variables.py b/src/ansys/fluent/visualization/pyvista/solution_variables.py new file mode 100644 index 00000000..5bfbdf80 --- /dev/null +++ b/src/ansys/fluent/visualization/pyvista/solution_variables.py @@ -0,0 +1,114 @@ +"""Module to display solution variables data.""" + +from enum import Enum +from typing import Callable, Optional, Union + +from ansys.fluent.core.session_solver import Solver +import numpy as np +import pyvista as pv + +from ansys.fluent.visualization.pyvista.pyvista_objects import ( + Graphics, + pyvista_windows_manager, +) + + +class Format(Enum): + DATA_ONLY = 1 + INDEX_AND_DATA = 2 + + +def display_solution_variables_data( + session: Solver, + variables: list[str], + zones: list[str], + domain: Optional[str] = "mixture", + format: Union[Format, Callable] = Format.INDEX_AND_DATA, + precision: int = 2, + font_size: int = 10, + bold: bool = False, +) -> "Plotter": + """Display solution variables data. The data is displayed as point labels + on the centroid of mesh-elements of the specified zones. + + Parameters + ---------- + session : Solver + PyFluent solver session from which solution variables data will be fetched. + variables : list[str] + List of solution variable names. To see the list of available solution + variable names, execute + ``session.fields.solution_variable_info.get_variables_info(zones, domain).solution_variables``. # noqa: E501 + zones : list[str] + List of zone names. + domain : str, optional + Domain name, by default ``"mixture"``. + format : Union[Format, Callable], optional + How to format the data label, by default ``Format.INDEX_AND_DATA``. + If a callable is provided, it should accept the index and the data as arguments. + precision : int, optional + Precision to show in the data label, by default 2. + font_size : int, optional + Font size of the data label, by default 10. + bold : bool, optional + Whether to show the data label in bold, by default False. + + Returns + ------- + Plotter + The PyVista plotter object. + + Examples + -------- + Display pressure and temperature data of "inlet1". + >>> display_solution_variables_data(session=session, variables=["SV_P", "SV_T"], zones=["inlet1"]) # noqa: E501 + Display pressure and temperature data of "inlet1" with custom format. + >>> display_solution_variables_data(session=session, variables=["SV_P", "SV_T"], zones=["inlet1"], format=lambda i, x, y: f"{i}: {x:.2f}, {y:.2f}") # noqa: E501 + """ + centroid_data = session.fields.solution_variable_data.get_data( + solution_variable_name="SV_CENTROID", zone_names=zones, domain_name=domain + ) + centroid_data = np.concatenate(list(centroid_data.data.values())).reshape(-1, 3) + + variables_data = [] + for variable in variables: + variable_data = session.fields.solution_variable_data.get_data( + solution_variable_name=variable, zone_names=zones, domain_name=domain + ) + variable_data = np.concatenate(list(variable_data.data.values())) + variables_data.append(variable_data.tolist()) + + def format_fn(index, *data): + if format == Format.DATA_ONLY: + if len(data) == 1: + return f"{data[0]:.{precision}f}" + else: + data_fmt = ", ".join(f"{d:.{precision}f}" for d in data) + return f"({data_fmt})" + elif format == Format.INDEX_AND_DATA: + data_fmt = ", ".join(f"{d:.{precision}f}" for d in data) + return f"({index}, {data_fmt})" + elif callable(format): + return format(index, *data) + + poly = pv.PolyData(centroid_data) + poly["Pressure"] = [ + format_fn(index, *data) for index, data in enumerate(zip(*variables_data)) + ] + graphics = Graphics(session=session) + mesh_name = graphics.Meshes.Create() + mesh = graphics.Meshes[mesh_name] + mesh.show_edges = True + mesh.surfaces_list = zones + window_id = pyvista_windows_manager._get_unique_window_id() + mesh.display(window_id) + plotter = pyvista_windows_manager.get_plotter(window_id) + plotter.add_point_labels( + poly, + "Pressure", + point_color="black", + font_size=font_size, + bold=bold, + shape=None, + ) + return plotter From 3ea216456b8e0cbdee5afee1d99af72b5584e677 Mon Sep 17 00:00:00 2001 From: Mainak Kundu Date: Fri, 21 Jun 2024 22:04:42 -0400 Subject: [PATCH 2/2] doc --- doc/source/api/visualization/index.rst | 1 + .../api/visualization/solution_variables.rst | 7 ++++ .../pyvista/solution_variables.py | 35 ++++++++++++------- 3 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 doc/source/api/visualization/solution_variables.rst diff --git a/doc/source/api/visualization/index.rst b/doc/source/api/visualization/index.rst index 5f1da46b..8405a21c 100644 --- a/doc/source/api/visualization/index.rst +++ b/doc/source/api/visualization/index.rst @@ -117,3 +117,4 @@ environment. Matplotlib is then used to plot data. :hidden: post_objects + solution_variables diff --git a/doc/source/api/visualization/solution_variables.rst b/doc/source/api/visualization/solution_variables.rst new file mode 100644 index 00000000..ad81c889 --- /dev/null +++ b/doc/source/api/visualization/solution_variables.rst @@ -0,0 +1,7 @@ +.. _ref_solution_variables: + +Display solution variables data +=============================== + +.. automodule:: ansys.fluent.visualization.pyvista.solution_variables + :members: \ No newline at end of file diff --git a/src/ansys/fluent/visualization/pyvista/solution_variables.py b/src/ansys/fluent/visualization/pyvista/solution_variables.py index 5bfbdf80..a5bed9d0 100644 --- a/src/ansys/fluent/visualization/pyvista/solution_variables.py +++ b/src/ansys/fluent/visualization/pyvista/solution_variables.py @@ -14,6 +14,8 @@ class Format(Enum): + """Format of the data label.""" + DATA_ONLY = 1 INDEX_AND_DATA = 2 @@ -27,7 +29,7 @@ def display_solution_variables_data( precision: int = 2, font_size: int = 10, bold: bool = False, -) -> "Plotter": +): """Display solution variables data. The data is displayed as point labels on the centroid of mesh-elements of the specified zones. @@ -36,14 +38,15 @@ def display_solution_variables_data( session : Solver PyFluent solver session from which solution variables data will be fetched. variables : list[str] - List of solution variable names. To see the list of available solution - variable names, execute - ``session.fields.solution_variable_info.get_variables_info(zones, domain).solution_variables``. # noqa: E501 + List of solution variable names whose data will be displayed. To see the + list of available solution variable names, execute + ``session.fields.solution_variable_info.get_variables_info(zones, + domain).solution_variables``. zones : list[str] - List of zone names. + List of zone names over which the data will be displayed. domain : str, optional Domain name, by default ``"mixture"``. - format : Union[Format, Callable], optional + format : Format or Callable, optional How to format the data label, by default ``Format.INDEX_AND_DATA``. If a callable is provided, it should accept the index and the data as arguments. precision : int, optional @@ -60,10 +63,18 @@ def display_solution_variables_data( Examples -------- - Display pressure and temperature data of "inlet1". - >>> display_solution_variables_data(session=session, variables=["SV_P", "SV_T"], zones=["inlet1"]) # noqa: E501 - Display pressure and temperature data of "inlet1" with custom format. - >>> display_solution_variables_data(session=session, variables=["SV_P", "SV_T"], zones=["inlet1"], format=lambda i, x, y: f"{i}: {x:.2f}, {y:.2f}") # noqa: E501 + Display pressure and temperature data of zone "inlet1". + + >>> display_solution_variables_data( + ... session=session, variables=["SV_P", "SV_T"], zones=["inlet1"] + ... ) + + Display pressure and temperature data of zone "inlet1" using a format function. + + >>> display_solution_variables_data( + ... session=session, variables=["SV_P", "SV_T"], zones=["inlet1"], + ... format=lambda i, x, y: f"{i}: {x:.2f}, {y:.2f}" + ... ) """ centroid_data = session.fields.solution_variable_data.get_data( solution_variable_name="SV_CENTROID", zone_names=zones, domain_name=domain @@ -92,7 +103,7 @@ def format_fn(index, *data): return format(index, *data) poly = pv.PolyData(centroid_data) - poly["Pressure"] = [ + poly["Data"] = [ format_fn(index, *data) for index, data in enumerate(zip(*variables_data)) ] graphics = Graphics(session=session) @@ -105,7 +116,7 @@ def format_fn(index, *data): plotter = pyvista_windows_manager.get_plotter(window_id) plotter.add_point_labels( poly, - "Pressure", + "Data", point_color="black", font_size=font_size, bold=bold,