diff --git a/src/ansys/fluent/core/codegen/walk_api.py b/src/ansys/fluent/core/codegen/walk_api.py new file mode 100644 index 00000000000..c21983fb364 --- /dev/null +++ b/src/ansys/fluent/core/codegen/walk_api.py @@ -0,0 +1,57 @@ +"""Module containing tool for walking (generated) API class hierarchy. + +Example +------- + +.. code-block:: python + + >>> from ansys.fluent.core.codegen import walk_api + >>> from ansys.fluent.core.generated.solver import settings_252 + >>> walk_api.walk_api(settings_252.root, lambda p: print(p), current_path=[]) + +""" + +from typing import List + + +def walk_api(api_root_cls, on_each_path, current_path: str | List[str] = ""): + """ + Recursively traverse the API hierarchy, calling `on_each_path` for each item. + + Parameters: + - api_root_cls: The root class of the API hierarchy. + - on_each_path: A callback function to call for each path. + - current_path: The current path in the hierarchy (default: empty string). + Paths can be either dot-separated strings or string lists. The type is + determined by the client. + """ + # Skip the root path + if current_path: + on_each_path(current_path) + + # Get child names and their respective classes + all_names = [ + name + for attr in ("child_names", "argument_names", "command_names", "query_names") + for name in getattr(api_root_cls, attr, []) + ] + child_classes = getattr(api_root_cls, "_child_classes", {}) + + # Traverse each child + for child_name in all_names: + if child_name in child_classes: + child_cls = child_classes[child_name] + # Construct the new path + if isinstance(current_path, list): + new_path = current_path + [child_name] + else: + new_path = ( + f"{current_path}.{child_name}" if current_path else child_name + ) + # Recursively walk the child + walk_api(child_cls, on_each_path, new_path) + + # Delegate directly to any child_object_type (relevant for named objects) + child_object_type = getattr(api_root_cls, "child_object_type", None) + if child_object_type: + walk_api(child_cls, on_each_path, current_path) diff --git a/src/ansys/fluent/core/post_objects/post_helper.py b/src/ansys/fluent/core/post_objects/post_helper.py index 2be4a2b91e1..fce978ade7e 100644 --- a/src/ansys/fluent/core/post_objects/post_helper.py +++ b/src/ansys/fluent/core/post_objects/post_helper.py @@ -2,6 +2,9 @@ import re +from ansys.fluent.core.solver.flunits import get_si_unit_for_fluent_quantity +from ansys.fluent.core.utils.fluent_version import FluentVersion + class IncompleteISOSurfaceDefinition(RuntimeError): """Raised when iso-surface definition is incomplete.""" @@ -131,11 +134,18 @@ def get_vector_fields(self): def get_field_unit(self, field): """Returns the unit of the field.""" - quantity = self._field_unit_quantity(field) - if quantity == "*null*": - return "" - scheme_eval_str = f"(units/get-pretty-wb-units-from-dimension (units/inquire-dimension '{quantity}))" - return " ".join(self._scheme_str_to_py_list(scheme_eval_str)) + session = self.obj.get_root().session + if FluentVersion(session.scheme_eval.version) < FluentVersion.v252: + quantity = self._field_unit_quantity(field) + if quantity == "*null*": + return "" + scheme_eval_str = f"(units/get-pretty-wb-units-from-dimension (units/inquire-dimension '{quantity}))" + return " ".join(self._scheme_str_to_py_list(scheme_eval_str)) + else: + fields_info = self.field_info.get_fields_info() + for field_info in fields_info: + if field_info["solverName"] == field: + return get_si_unit_for_fluent_quantity(field_info["quantity_name"]) def _field_unit_quantity(self, field): scheme_eval_str = f"(cdr (assq 'units (%fill-render-info '{field})))" diff --git a/src/ansys/fluent/core/services/field_data.py b/src/ansys/fluent/core/services/field_data.py index b82f78ac10e..fb24d57fc8b 100644 --- a/src/ansys/fluent/core/services/field_data.py +++ b/src/ansys/fluent/core/services/field_data.py @@ -51,6 +51,10 @@ def __init__( stub=FieldGrpcModule.FieldDataStub(intercept_channel), metadata=metadata ) + def get_fields_info(self, request): + """GetFieldsInfo RPC of FieldData service.""" + return self._stub.GetFieldsInfo(request, metadata=self._metadata) + def get_scalar_field_range(self, request): """GetRange RPC of FieldData service.""" return self._stub.GetRange(request, metadata=self._metadata) @@ -88,6 +92,9 @@ class FieldInfo: Methods ------- + get_fields_info(field: str) -> List[dict] + Get fields info. + get_scalar_field_range(field: str, node_value: bool, surface_ids: List[int]) -> List[float] Get the range (minimum and maximum values) of the field. @@ -111,6 +118,17 @@ def __init__( self._service = service self._is_data_valid = is_data_valid + def get_fields_info(self) -> List[dict]: + """Get fields info. + + Returns + ------- + List[dict] + """ + request = FieldDataProtoModule.GetFieldsInfo() + response = self._service.get_fields_info(request) + return response["fieldInfo"] + def get_scalar_field_range( self, field: str, node_value: bool = False, surface_ids: List[int] = None ) -> List[float]: