ansys-fluent-core 0.29.dev0__py3-none-any.whl → 0.29.dev1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ansys-fluent-core might be problematic. Click here for more details.
- ansys/fluent/core/__init__.py +1 -1
- ansys/fluent/core/_version.py +2 -2
- ansys/fluent/core/codegen/tuigen.py +1 -1
- ansys/fluent/core/codegen/walk_api.py +45 -18
- ansys/fluent/core/generated/api_tree/api_objects.json +1 -1
- ansys/fluent/core/generated/datamodel_252/meshing.py +1 -0
- ansys/fluent/core/generated/datamodel_252/preferences.py +7 -0
- ansys/fluent/core/generated/fluent_version_252.py +3 -3
- ansys/fluent/core/generated/meshing/tui_252.py +395 -390
- ansys/fluent/core/generated/solver/settings_252.py +782 -306
- ansys/fluent/core/generated/solver/settings_252.pyi +442 -133
- ansys/fluent/core/generated/solver/tui_252.py +4046 -3737
- ansys/fluent/core/launcher/container_launcher.py +4 -3
- ansys/fluent/core/launcher/fluent_container.py +22 -19
- ansys/fluent/core/launcher/launcher.py +2 -2
- ansys/fluent/core/launcher/pim_launcher.py +2 -2
- ansys/fluent/core/launcher/slurm_launcher.py +2 -2
- ansys/fluent/core/launcher/standalone_launcher.py +2 -2
- ansys/fluent/core/logging.py +2 -0
- ansys/fluent/core/logging_config.yaml +3 -0
- ansys/fluent/core/services/app_utilities.py +2 -1
- ansys/fluent/core/services/datamodel_se.py +141 -61
- ansys/fluent/core/services/field_data.py +252 -0
- ansys/fluent/core/services/interceptors.py +28 -2
- ansys/fluent/core/session.py +7 -2
- ansys/fluent/core/session_solver.py +21 -0
- ansys/fluent/core/streaming_services/datamodel_event_streaming.py +12 -12
- {ansys_fluent_core-0.29.dev0.dist-info → ansys_fluent_core-0.29.dev1.dist-info}/LICENSE +1 -1
- {ansys_fluent_core-0.29.dev0.dist-info → ansys_fluent_core-0.29.dev1.dist-info}/METADATA +53 -31
- {ansys_fluent_core-0.29.dev0.dist-info → ansys_fluent_core-0.29.dev1.dist-info}/RECORD +65 -141
- {ansys_fluent_core-0.29.dev0.dist-info → ansys_fluent_core-0.29.dev1.dist-info}/WHEEL +1 -1
- ansys/fluent/core/docs/README.rst +0 -155
- ansys/fluent/tests/conftest.py +0 -415
- ansys/fluent/tests/fluent_fixtures.py +0 -195
- ansys/fluent/tests/integration/test_optislang/test_optislang_integration.py +0 -263
- ansys/fluent/tests/parametric/test_local_parametric_run.py +0 -36
- ansys/fluent/tests/parametric/test_local_parametric_setup.py +0 -34
- ansys/fluent/tests/parametric/test_parametric_workflow.py +0 -279
- ansys/fluent/tests/test_aero_session.py +0 -88
- ansys/fluent/tests/test_batch_ops.py +0 -39
- ansys/fluent/tests/test_builtin_settings.py +0 -761
- ansys/fluent/tests/test_cad_to_post_ftm.py +0 -525
- ansys/fluent/tests/test_cad_to_post_wtm.py +0 -250
- ansys/fluent/tests/test_casereader.py +0 -324
- ansys/fluent/tests/test_codegen.py +0 -783
- ansys/fluent/tests/test_creatable.py +0 -31
- ansys/fluent/tests/test_data_model_cache.py +0 -434
- ansys/fluent/tests/test_datamodel_api.py +0 -449
- ansys/fluent/tests/test_datamodel_service.py +0 -814
- ansys/fluent/tests/test_datareader.py +0 -103
- ansys/fluent/tests/test_error_handling.py +0 -24
- ansys/fluent/tests/test_events_manager.py +0 -214
- ansys/fluent/tests/test_field_data.py +0 -466
- ansys/fluent/tests/test_file_session.py +0 -355
- ansys/fluent/tests/test_file_transfer_service.py +0 -165
- ansys/fluent/tests/test_fix_doc.py +0 -29
- ansys/fluent/tests/test_flobject.py +0 -1235
- ansys/fluent/tests/test_fluent_fixes.py +0 -106
- ansys/fluent/tests/test_fluent_session.py +0 -270
- ansys/fluent/tests/test_fluent_version.py +0 -66
- ansys/fluent/tests/test_fluent_version_marker.py +0 -65
- ansys/fluent/tests/test_icing_session.py +0 -9
- ansys/fluent/tests/test_launcher.py +0 -529
- ansys/fluent/tests/test_launcher_remote.py +0 -272
- ansys/fluent/tests/test_lispy.py +0 -40
- ansys/fluent/tests/test_logging.py +0 -16
- ansys/fluent/tests/test_mapped_api.py +0 -774
- ansys/fluent/tests/test_meshing_utilities.py +0 -2436
- ansys/fluent/tests/test_meshing_workflow.py +0 -421
- ansys/fluent/tests/test_meshingmode/test_meshing_launch.py +0 -168
- ansys/fluent/tests/test_new_meshing_workflow.py +0 -1801
- ansys/fluent/tests/test_preferences.py +0 -89
- ansys/fluent/tests/test_pure_mesh_vs_mesh_workflow.py +0 -101
- ansys/fluent/tests/test_reduction.py +0 -484
- ansys/fluent/tests/test_rp_vars.py +0 -77
- ansys/fluent/tests/test_scheduler.py +0 -471
- ansys/fluent/tests/test_scheme_eval_222.py +0 -338
- ansys/fluent/tests/test_scheme_eval_231.py +0 -243
- ansys/fluent/tests/test_search.py +0 -344
- ansys/fluent/tests/test_session.py +0 -594
- ansys/fluent/tests/test_settings_api.py +0 -606
- ansys/fluent/tests/test_settings_reader.py +0 -85
- ansys/fluent/tests/test_slurm_future.py +0 -67
- ansys/fluent/tests/test_solution_variables.py +0 -241
- ansys/fluent/tests/test_solver_monitors.py +0 -83
- ansys/fluent/tests/test_solvermode/boundaries_periodic_expDict +0 -1712
- ansys/fluent/tests/test_solvermode/test_boundaries.py +0 -127
- ansys/fluent/tests/test_solvermode/test_calculationactivities.py +0 -20
- ansys/fluent/tests/test_solvermode/test_controls.py +0 -131
- ansys/fluent/tests/test_solvermode/test_general.py +0 -109
- ansys/fluent/tests/test_solvermode/test_initialization.py +0 -83
- ansys/fluent/tests/test_solvermode/test_materials.py +0 -40
- ansys/fluent/tests/test_solvermode/test_methods.py +0 -65
- ansys/fluent/tests/test_solvermode/test_models.py +0 -99
- ansys/fluent/tests/test_solvermode/test_named_expressions.py +0 -35
- ansys/fluent/tests/test_solvermode/test_post_vector.py +0 -22
- ansys/fluent/tests/test_solvermode/test_species_model.py +0 -67
- ansys/fluent/tests/test_streaming_services.py +0 -52
- ansys/fluent/tests/test_systemcoupling.py +0 -44
- ansys/fluent/tests/test_topy.py +0 -179
- ansys/fluent/tests/test_tui_api.py +0 -70
- ansys/fluent/tests/test_type_stub.py +0 -37
- ansys/fluent/tests/test_utils.py +0 -82
- ansys/fluent/tests/util/__init__.py +0 -36
- ansys/fluent/tests/util/meshing_workflow.py +0 -33
- ansys/fluent/tests/util/solver.py +0 -72
- ansys_fluent_core-0.29.dev0.dist-info/AUTHORS +0 -12
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
"""Wrappers over FieldData gRPC service of Fluent."""
|
|
2
2
|
|
|
3
|
+
from dataclasses import dataclass, field
|
|
3
4
|
from enum import Enum
|
|
4
5
|
from functools import reduce
|
|
6
|
+
import logging
|
|
7
|
+
import time
|
|
5
8
|
from typing import Callable, Dict, List, Tuple
|
|
9
|
+
import weakref
|
|
6
10
|
|
|
7
11
|
import grpc
|
|
8
12
|
import numpy as np
|
|
@@ -19,6 +23,8 @@ from ansys.fluent.core.services.interceptors import (
|
|
|
19
23
|
from ansys.fluent.core.services.streaming import StreamingService
|
|
20
24
|
from ansys.fluent.core.utils.deprecate import deprecate_argument, deprecate_arguments
|
|
21
25
|
|
|
26
|
+
logger = logging.getLogger("pyfluent.field_data")
|
|
27
|
+
|
|
22
28
|
|
|
23
29
|
def override_help_text(func, func_to_be_wrapped):
|
|
24
30
|
"""Override function help text."""
|
|
@@ -82,6 +88,28 @@ class FieldDataService(StreamingService):
|
|
|
82
88
|
)
|
|
83
89
|
return chunk_iterator
|
|
84
90
|
|
|
91
|
+
def get_solver_mesh_nodes(
|
|
92
|
+
self, request: FieldDataProtoModule.GetSolverMeshNodesRequest
|
|
93
|
+
):
|
|
94
|
+
"""GetSolverMeshNodesDouble RPC of FieldData service."""
|
|
95
|
+
responses = self._stub.GetSolverMeshNodesDouble(
|
|
96
|
+
request, metadata=self._metadata
|
|
97
|
+
)
|
|
98
|
+
nested_nodes = []
|
|
99
|
+
for response in responses:
|
|
100
|
+
nested_nodes.append(response.nodes)
|
|
101
|
+
return nested_nodes
|
|
102
|
+
|
|
103
|
+
def get_solver_mesh_elements(
|
|
104
|
+
self, request: FieldDataProtoModule.GetSolverMeshElementsRequest
|
|
105
|
+
):
|
|
106
|
+
"""GetSolverMeshElements RPC of FieldData service."""
|
|
107
|
+
responses = self._stub.GetSolverMeshElements(request, metadata=self._metadata)
|
|
108
|
+
elementss = []
|
|
109
|
+
for response in responses:
|
|
110
|
+
elementss.append(response.elements)
|
|
111
|
+
return elementss
|
|
112
|
+
|
|
85
113
|
|
|
86
114
|
class FieldInfo:
|
|
87
115
|
"""Provides access to Fluent field information.
|
|
@@ -922,6 +950,134 @@ class ChunkParser:
|
|
|
922
950
|
return fields_data
|
|
923
951
|
|
|
924
952
|
|
|
953
|
+
# Root domain id in Fluent.
|
|
954
|
+
ROOT_DOMAIN_ID = 1
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
class ZoneType(Enum):
|
|
958
|
+
"""Zone types for mesh."""
|
|
959
|
+
|
|
960
|
+
CELL = 1
|
|
961
|
+
FACE = 2
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
@dataclass
|
|
965
|
+
class ZoneInfo:
|
|
966
|
+
"""Zone information for mesh.
|
|
967
|
+
|
|
968
|
+
Attributes:
|
|
969
|
+
-----------
|
|
970
|
+
_id : int
|
|
971
|
+
Zone ID.
|
|
972
|
+
name : str
|
|
973
|
+
Name of the zone.
|
|
974
|
+
zone_type : ZoneType
|
|
975
|
+
Type of the zone for mesh.
|
|
976
|
+
"""
|
|
977
|
+
|
|
978
|
+
_id: int
|
|
979
|
+
name: str
|
|
980
|
+
zone_type: ZoneType
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
@dataclass
|
|
984
|
+
class Node:
|
|
985
|
+
"""Node class for mesh.
|
|
986
|
+
|
|
987
|
+
Attributes:
|
|
988
|
+
-----------
|
|
989
|
+
x : float
|
|
990
|
+
x-coordinate of the node.
|
|
991
|
+
y : float
|
|
992
|
+
y-coordinate of the node.
|
|
993
|
+
z : float
|
|
994
|
+
z-coordinate of the node.
|
|
995
|
+
"""
|
|
996
|
+
|
|
997
|
+
_id: int
|
|
998
|
+
x: float
|
|
999
|
+
y: float
|
|
1000
|
+
z: float
|
|
1001
|
+
|
|
1002
|
+
|
|
1003
|
+
class CellElementType(Enum):
|
|
1004
|
+
"""Element types for a cell element."""
|
|
1005
|
+
|
|
1006
|
+
# 3 nodes, 3 faces
|
|
1007
|
+
TRIANGLE = 1
|
|
1008
|
+
# 4 nodes, 4 faces
|
|
1009
|
+
TETRAHEDRON = 2
|
|
1010
|
+
# 4 nodes, 4 faces
|
|
1011
|
+
QUADRILATERAL = 3
|
|
1012
|
+
# 8 nodes, 6 faces
|
|
1013
|
+
HEXAHEDRON = 4
|
|
1014
|
+
# 5 nodes, 5 faces
|
|
1015
|
+
PYRAMID = 5
|
|
1016
|
+
# 6 nodes, 5 faces
|
|
1017
|
+
WEDGE = 6
|
|
1018
|
+
# Arbitrary number of nodes and faces
|
|
1019
|
+
POLYHEDRON = 7
|
|
1020
|
+
# 2 nodes, 1 face (only in 2D)
|
|
1021
|
+
GHOST = 8
|
|
1022
|
+
# 10 nodes, 4 faces
|
|
1023
|
+
QUADRATIC_TETRAHEDRON = 9
|
|
1024
|
+
# 20 nodes, 6 faces
|
|
1025
|
+
QUADRATIC_HEXAHEDRON = 10
|
|
1026
|
+
# 13 nodes, 5 faces
|
|
1027
|
+
QUADRATIC_PYRAMID = 11
|
|
1028
|
+
# 15 nodes, 5 faces
|
|
1029
|
+
QUADRATIC_WEDGE = 12
|
|
1030
|
+
|
|
1031
|
+
|
|
1032
|
+
@dataclass
|
|
1033
|
+
class Facet:
|
|
1034
|
+
"""Facet class within a mesh element.
|
|
1035
|
+
|
|
1036
|
+
Attributes:
|
|
1037
|
+
-----------
|
|
1038
|
+
node_indices : list[int]
|
|
1039
|
+
0-based node indices of the facet.
|
|
1040
|
+
"""
|
|
1041
|
+
|
|
1042
|
+
node_indices: list[int]
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
@dataclass
|
|
1046
|
+
class Element:
|
|
1047
|
+
"""Element class for mesh.
|
|
1048
|
+
|
|
1049
|
+
Attributes:
|
|
1050
|
+
-----------
|
|
1051
|
+
element_type : CellElementType
|
|
1052
|
+
Element type of the element.
|
|
1053
|
+
node_indices : list[int]
|
|
1054
|
+
0-based node indices of the element. Populated for standard elements.
|
|
1055
|
+
facets : list[Facet]
|
|
1056
|
+
List of facets of the element. Populated for polyhedral elements.
|
|
1057
|
+
"""
|
|
1058
|
+
|
|
1059
|
+
_id: int
|
|
1060
|
+
element_type: CellElementType
|
|
1061
|
+
node_indices: list[int] = field(default_factory=list)
|
|
1062
|
+
facets: list[Facet] = field(default_factory=list)
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
@dataclass
|
|
1066
|
+
class Mesh:
|
|
1067
|
+
"""Mesh class for Fluent field data.
|
|
1068
|
+
|
|
1069
|
+
Attributes:
|
|
1070
|
+
-----------
|
|
1071
|
+
nodes : list[Node]
|
|
1072
|
+
List of nodes in the mesh.
|
|
1073
|
+
elements : list[Element]
|
|
1074
|
+
List of elements in the mesh.
|
|
1075
|
+
"""
|
|
1076
|
+
|
|
1077
|
+
nodes: list[Node]
|
|
1078
|
+
elements: list[Element]
|
|
1079
|
+
|
|
1080
|
+
|
|
925
1081
|
class FieldData:
|
|
926
1082
|
"""Provides access to Fluent field data on surfaces."""
|
|
927
1083
|
|
|
@@ -931,12 +1087,14 @@ class FieldData:
|
|
|
931
1087
|
field_info: FieldInfo,
|
|
932
1088
|
is_data_valid: Callable[[], bool],
|
|
933
1089
|
scheme_eval=None,
|
|
1090
|
+
get_zones_info: weakref.WeakMethod[Callable[[], list[ZoneInfo]]] | None = None,
|
|
934
1091
|
):
|
|
935
1092
|
"""__init__ method of FieldData class."""
|
|
936
1093
|
self._service = service
|
|
937
1094
|
self._field_info = field_info
|
|
938
1095
|
self.is_data_valid = is_data_valid
|
|
939
1096
|
self.scheme_eval = scheme_eval
|
|
1097
|
+
self.get_zones_info = lambda: get_zones_info()()
|
|
940
1098
|
|
|
941
1099
|
self._allowed_surface_names = _AllowedSurfaceNames(field_info)
|
|
942
1100
|
|
|
@@ -1285,3 +1443,97 @@ class FieldData:
|
|
|
1285
1443
|
field_name: pathlines_data[surface_ids[count]][field_name],
|
|
1286
1444
|
}
|
|
1287
1445
|
return path_lines_dict
|
|
1446
|
+
|
|
1447
|
+
def get_mesh(self, zone: str | int) -> Mesh:
|
|
1448
|
+
"""Get mesh for a zone.
|
|
1449
|
+
|
|
1450
|
+
Parameters
|
|
1451
|
+
----------
|
|
1452
|
+
zone : str | int
|
|
1453
|
+
Zone name or id. Currently, only cell zones are supported.
|
|
1454
|
+
|
|
1455
|
+
Returns
|
|
1456
|
+
-------
|
|
1457
|
+
Mesh
|
|
1458
|
+
Mesh object containing nodes and elements.
|
|
1459
|
+
|
|
1460
|
+
Raises
|
|
1461
|
+
------
|
|
1462
|
+
ValueError
|
|
1463
|
+
If the zone is not found.
|
|
1464
|
+
NotImplementedError
|
|
1465
|
+
If a face zone is provided.
|
|
1466
|
+
"""
|
|
1467
|
+
zone_info = None
|
|
1468
|
+
for zone_info in self.get_zones_info():
|
|
1469
|
+
if zone_info.name == zone or zone_info._id == zone:
|
|
1470
|
+
break
|
|
1471
|
+
if zone_info is None:
|
|
1472
|
+
raise ValueError(f"Zone {zone} not found.")
|
|
1473
|
+
if zone_info.zone_type == ZoneType.FACE:
|
|
1474
|
+
raise NotImplementedError("Face zone mesh is not supported.")
|
|
1475
|
+
|
|
1476
|
+
# Mesh data is retrieved from the root domain in Fluent
|
|
1477
|
+
logger.info(f"Getting nodes data for zone {zone_info._id}")
|
|
1478
|
+
start_time = time.time()
|
|
1479
|
+
nodes_request = FieldDataProtoModule.GetSolverMeshNodesRequest(
|
|
1480
|
+
domain_id=ROOT_DOMAIN_ID, thread_id=zone_info._id
|
|
1481
|
+
)
|
|
1482
|
+
nested_nodes = self._service.get_solver_mesh_nodes(nodes_request)
|
|
1483
|
+
logger.info(f"Nodes data received in {time.time() - start_time} seconds")
|
|
1484
|
+
logger.info(f"Getting elements for zone {zone_info._id}")
|
|
1485
|
+
start_time = time.time()
|
|
1486
|
+
elements_request = FieldDataProtoModule.GetSolverMeshElementsRequest(
|
|
1487
|
+
domain_id=ROOT_DOMAIN_ID, thread_id=zone_info._id
|
|
1488
|
+
)
|
|
1489
|
+
elementss_pb = self._service.get_solver_mesh_elements(elements_request)
|
|
1490
|
+
logger.info(f"Elements data received in {time.time() - start_time} seconds")
|
|
1491
|
+
logger.info("Constructing nodes structure in PyFluent")
|
|
1492
|
+
start_time = time.time()
|
|
1493
|
+
node_count = sum(len(nodes) for nodes in nested_nodes)
|
|
1494
|
+
nodes = np.empty(node_count, dtype=Node)
|
|
1495
|
+
node_index_by_id = {}
|
|
1496
|
+
i = 0
|
|
1497
|
+
for nodes_pb in nested_nodes:
|
|
1498
|
+
for node_pb in nodes_pb:
|
|
1499
|
+
nodes[i] = Node(_id=node_pb.id, x=node_pb.x, y=node_pb.y, z=node_pb.z)
|
|
1500
|
+
node_index_by_id[node_pb.id] = i
|
|
1501
|
+
i += 1
|
|
1502
|
+
logger.info(
|
|
1503
|
+
f"Nodes structure constructed in {time.time() - start_time} seconds"
|
|
1504
|
+
)
|
|
1505
|
+
logger.info("Constructing elements structure in PyFluent")
|
|
1506
|
+
start_time = time.time()
|
|
1507
|
+
element_count = sum(len(elements) for elements in elementss_pb)
|
|
1508
|
+
elements = np.empty(element_count, dtype=Element)
|
|
1509
|
+
i = 0
|
|
1510
|
+
for elements_pb in elementss_pb:
|
|
1511
|
+
for element_pb in elements_pb:
|
|
1512
|
+
element_type = CellElementType(element_pb.element_type)
|
|
1513
|
+
if element_type == CellElementType.POLYHEDRON:
|
|
1514
|
+
facets = []
|
|
1515
|
+
for facet_pb in element_pb.facets:
|
|
1516
|
+
facet = Facet(
|
|
1517
|
+
node_indices=[node_index_by_id[id] for id in facet_pb.node]
|
|
1518
|
+
)
|
|
1519
|
+
facets.append(facet)
|
|
1520
|
+
element = Element(
|
|
1521
|
+
_id=element_pb.id,
|
|
1522
|
+
element_type=element_type,
|
|
1523
|
+
facets=facets,
|
|
1524
|
+
)
|
|
1525
|
+
else:
|
|
1526
|
+
element = Element(
|
|
1527
|
+
_id=element_pb.id,
|
|
1528
|
+
element_type=element_type,
|
|
1529
|
+
node_indices=[
|
|
1530
|
+
node_index_by_id[id] for id in element_pb.node_ids
|
|
1531
|
+
],
|
|
1532
|
+
)
|
|
1533
|
+
elements[i] = element
|
|
1534
|
+
i += 1
|
|
1535
|
+
logger.info(
|
|
1536
|
+
f"Elements structure constructed in {time.time() - start_time} seconds"
|
|
1537
|
+
)
|
|
1538
|
+
logger.info("Returning mesh")
|
|
1539
|
+
return Mesh(nodes=nodes, elements=elements)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"""Interceptor classes to use with gRPC services."""
|
|
2
2
|
|
|
3
|
+
import builtins
|
|
3
4
|
import logging
|
|
4
5
|
import os
|
|
5
6
|
from typing import Any
|
|
6
7
|
|
|
7
8
|
from google.protobuf.json_format import MessageToDict
|
|
8
|
-
from google.protobuf.message import Message
|
|
9
|
+
from google.protobuf.message import DecodeError, Message
|
|
9
10
|
import grpc
|
|
10
11
|
|
|
11
12
|
from ansys.fluent.core.services.batch_ops import BatchOps
|
|
@@ -15,6 +16,10 @@ log_bytes_limit: int = int(os.getenv("PYFLUENT_GRPC_LOG_BYTES_LIMIT", 1000))
|
|
|
15
16
|
truncate_len: int = log_bytes_limit // 5
|
|
16
17
|
|
|
17
18
|
|
|
19
|
+
def _upper_snake_case_to_camel_case(name: str) -> str:
|
|
20
|
+
return "".join([word.capitalize() for word in name.split("_") if word])
|
|
21
|
+
|
|
22
|
+
|
|
18
23
|
def _truncate_grpc_str(message: Message) -> str:
|
|
19
24
|
message_bytes = message.ByteSize()
|
|
20
25
|
message_str = str(MessageToDict(message))
|
|
@@ -107,7 +112,28 @@ class GrpcErrorInterceptor(grpc.UnaryUnaryClientInterceptor):
|
|
|
107
112
|
response = continuation(client_call_details, request)
|
|
108
113
|
if response.exception() is not None and response.code() != grpc.StatusCode.OK:
|
|
109
114
|
ex = response.exception()
|
|
110
|
-
|
|
115
|
+
new_ex_cls = RuntimeError
|
|
116
|
+
try:
|
|
117
|
+
from google.rpc import error_details_pb2
|
|
118
|
+
from grpc_status import rpc_status
|
|
119
|
+
|
|
120
|
+
status = rpc_status.from_call(ex)
|
|
121
|
+
if status:
|
|
122
|
+
for detail in status.details:
|
|
123
|
+
if detail.Is(error_details_pb2.ErrorInfo.DESCRIPTOR):
|
|
124
|
+
info = error_details_pb2.ErrorInfo()
|
|
125
|
+
detail.Unpack(info)
|
|
126
|
+
if info.domain == "Python":
|
|
127
|
+
reason = info.reason
|
|
128
|
+
ex_cls_name = _upper_snake_case_to_camel_case(reason)
|
|
129
|
+
if hasattr(builtins, ex_cls_name):
|
|
130
|
+
cls = getattr(builtins, ex_cls_name)
|
|
131
|
+
if issubclass(cls, Exception):
|
|
132
|
+
new_ex_cls = cls
|
|
133
|
+
break
|
|
134
|
+
except DecodeError:
|
|
135
|
+
pass
|
|
136
|
+
new_ex = new_ex_cls(
|
|
111
137
|
ex.details() if isinstance(ex, grpc.RpcError) else str(ex)
|
|
112
138
|
)
|
|
113
139
|
new_ex.__context__ = ex
|
ansys/fluent/core/session.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from enum import Enum
|
|
4
4
|
import json
|
|
5
5
|
import logging
|
|
6
|
-
from typing import Any, Dict
|
|
6
|
+
from typing import Any, Callable, Dict
|
|
7
7
|
import warnings
|
|
8
8
|
import weakref
|
|
9
9
|
|
|
@@ -11,7 +11,7 @@ from ansys.fluent.core.fluent_connection import FluentConnection
|
|
|
11
11
|
from ansys.fluent.core.journaling import Journal
|
|
12
12
|
from ansys.fluent.core.services import service_creator
|
|
13
13
|
from ansys.fluent.core.services.app_utilities import AppUtilitiesOld
|
|
14
|
-
from ansys.fluent.core.services.field_data import FieldDataService
|
|
14
|
+
from ansys.fluent.core.services.field_data import FieldDataService, ZoneInfo
|
|
15
15
|
from ansys.fluent.core.services.scheme_eval import SchemeEval
|
|
16
16
|
from ansys.fluent.core.streaming_services.datamodel_event_streaming import (
|
|
17
17
|
DatamodelEvents,
|
|
@@ -85,6 +85,7 @@ class BaseSession:
|
|
|
85
85
|
Close the Fluent connection and exit Fluent.
|
|
86
86
|
"""
|
|
87
87
|
|
|
88
|
+
# We are passing around an WeakMethod to avoid circular references
|
|
88
89
|
def __init__(
|
|
89
90
|
self,
|
|
90
91
|
fluent_connection: FluentConnection,
|
|
@@ -93,6 +94,7 @@ class BaseSession:
|
|
|
93
94
|
start_transcript: bool = True,
|
|
94
95
|
launcher_args: Dict[str, Any] | None = None,
|
|
95
96
|
event_type: Enum | None = None,
|
|
97
|
+
get_zones_info: weakref.WeakMethod[Callable[[], list[ZoneInfo]]] | None = None,
|
|
96
98
|
):
|
|
97
99
|
"""BaseSession.
|
|
98
100
|
|
|
@@ -120,6 +122,7 @@ class BaseSession:
|
|
|
120
122
|
scheme_eval,
|
|
121
123
|
file_transfer_service,
|
|
122
124
|
event_type,
|
|
125
|
+
get_zones_info,
|
|
123
126
|
)
|
|
124
127
|
|
|
125
128
|
def _build_from_fluent_connection(
|
|
@@ -128,6 +131,7 @@ class BaseSession:
|
|
|
128
131
|
scheme_eval: SchemeEval,
|
|
129
132
|
file_transfer_service: Any | None = None,
|
|
130
133
|
event_type=None,
|
|
134
|
+
get_zones_info: weakref.WeakMethod[Callable[[], list[ZoneInfo]]] | None = None,
|
|
131
135
|
):
|
|
132
136
|
"""Build a BaseSession object from fluent_connection object."""
|
|
133
137
|
self._fluent_connection = fluent_connection
|
|
@@ -205,6 +209,7 @@ class BaseSession:
|
|
|
205
209
|
self.field_info,
|
|
206
210
|
self._is_solution_data_valid,
|
|
207
211
|
_session.scheme_eval,
|
|
212
|
+
get_zones_info,
|
|
208
213
|
)
|
|
209
214
|
self.field_data_streaming = FieldDataStreaming(
|
|
210
215
|
_session._fluent_connection._id, _session._field_data_service
|
|
@@ -6,9 +6,12 @@ import logging
|
|
|
6
6
|
import threading
|
|
7
7
|
from typing import Any, Dict
|
|
8
8
|
import warnings
|
|
9
|
+
import weakref
|
|
9
10
|
|
|
11
|
+
from ansys.api.fluent.v0 import svar_pb2 as SvarProtoModule
|
|
10
12
|
import ansys.fluent.core as pyfluent
|
|
11
13
|
from ansys.fluent.core.services import SchemeEval, service_creator
|
|
14
|
+
from ansys.fluent.core.services.field_data import ZoneInfo, ZoneType
|
|
12
15
|
from ansys.fluent.core.services.reduction import ReductionService
|
|
13
16
|
from ansys.fluent.core.services.solution_variables import (
|
|
14
17
|
SolutionVariableData,
|
|
@@ -106,6 +109,7 @@ class Solver(BaseSession):
|
|
|
106
109
|
start_transcript=start_transcript,
|
|
107
110
|
launcher_args=launcher_args,
|
|
108
111
|
event_type=SolverEvent,
|
|
112
|
+
get_zones_info=weakref.WeakMethod(self._get_zones_info),
|
|
109
113
|
)
|
|
110
114
|
self._build_from_fluent_connection(fluent_connection, scheme_eval)
|
|
111
115
|
|
|
@@ -176,6 +180,23 @@ class Solver(BaseSession):
|
|
|
176
180
|
)
|
|
177
181
|
return self.fields.solution_variable_info
|
|
178
182
|
|
|
183
|
+
def _get_zones_info(self) -> list[ZoneInfo]:
|
|
184
|
+
zones_info = []
|
|
185
|
+
for (
|
|
186
|
+
zone_info
|
|
187
|
+
) in self.fields.solution_variable_info.get_zones_info()._zones_info.values():
|
|
188
|
+
zone_type = (
|
|
189
|
+
ZoneType.CELL
|
|
190
|
+
if zone_info.thread_type == SvarProtoModule.ThreadType.CELL_THREAD
|
|
191
|
+
else ZoneType.FACE
|
|
192
|
+
)
|
|
193
|
+
zones_info.append(
|
|
194
|
+
ZoneInfo(
|
|
195
|
+
_id=zone_info.zone_id, name=zone_info.name, zone_type=zone_type
|
|
196
|
+
)
|
|
197
|
+
)
|
|
198
|
+
return zones_info
|
|
199
|
+
|
|
179
200
|
@property
|
|
180
201
|
def reduction(self):
|
|
181
202
|
"""``Reduction`` handle."""
|
|
@@ -28,10 +28,10 @@ class DatamodelEvents(StreamingService):
|
|
|
28
28
|
service.event_streaming = self
|
|
29
29
|
self._lock = threading.RLock()
|
|
30
30
|
|
|
31
|
-
def register_callback(self, tag: str,
|
|
31
|
+
def register_callback(self, tag: str, cb: Callable):
|
|
32
32
|
"""Register a callback."""
|
|
33
33
|
with self._lock:
|
|
34
|
-
self._cbs[tag] =
|
|
34
|
+
self._cbs[tag] = cb
|
|
35
35
|
|
|
36
36
|
def unregister_callback(self, tag: str):
|
|
37
37
|
"""Unregister a callback."""
|
|
@@ -58,25 +58,25 @@ class DatamodelEvents(StreamingService):
|
|
|
58
58
|
if response.HasField("createdEventResponse"):
|
|
59
59
|
childtype = response.createdEventResponse.childtype
|
|
60
60
|
childname = response.createdEventResponse.childname
|
|
61
|
-
|
|
62
|
-
cb[1](child)
|
|
61
|
+
cb(childtype, childname)
|
|
63
62
|
elif response.HasField("attributeChangedEventResponse"):
|
|
64
63
|
value = response.attributeChangedEventResponse.value
|
|
65
|
-
cb
|
|
64
|
+
cb(_convert_variant_to_value(value))
|
|
66
65
|
elif response.HasField("commandAttributeChangedEventResponse"):
|
|
67
66
|
value = response.commandAttributeChangedEventResponse.value
|
|
68
|
-
cb
|
|
69
|
-
elif response.HasField(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
cb(_convert_variant_to_value(value))
|
|
68
|
+
elif response.HasField("modifiedEventResponse"):
|
|
69
|
+
value = response.modifiedEventResponse.value
|
|
70
|
+
cb(_convert_variant_to_value(value))
|
|
71
|
+
elif response.HasField("affectedEventResponse"):
|
|
72
|
+
cb()
|
|
73
73
|
elif response.HasField("deletedEventResponse"):
|
|
74
|
-
cb
|
|
74
|
+
cb()
|
|
75
75
|
elif response.HasField("commandExecutedEventResponse"):
|
|
76
76
|
command = response.commandExecutedEventResponse.command
|
|
77
77
|
args = _convert_variant_to_value(
|
|
78
78
|
response.commandExecutedEventResponse.args
|
|
79
79
|
)
|
|
80
|
-
cb
|
|
80
|
+
cb(command, args)
|
|
81
81
|
except StopIteration:
|
|
82
82
|
break
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2025 ANSYS, Inc. All rights reserved.
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,41 +1,63 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: ansys-fluent-core
|
|
3
|
-
Version: 0.29.
|
|
4
|
-
Summary: PyFluent provides Pythonic access to Ansys Fluent
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Maintainer: PyAnsys developers
|
|
10
|
-
Maintainer-email: pyansys.maintainers@ansys.com
|
|
11
|
-
Requires-Python: >=3.10,<4.0
|
|
3
|
+
Version: 0.29.dev1
|
|
4
|
+
Summary: PyFluent provides Pythonic access to Ansys Fluent.
|
|
5
|
+
Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
6
|
+
Maintainer-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
7
|
+
Requires-Python: >=3.10,<3.14
|
|
8
|
+
Description-Content-Type: text/x-rst
|
|
12
9
|
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
11
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
12
|
Classifier: Operating System :: OS Independent
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist:
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist:
|
|
13
|
+
Requires-Dist: ansys-api-fluent>=0.3.33
|
|
14
|
+
Requires-Dist: ansys-platform-instancemanagement~=1.0
|
|
15
|
+
Requires-Dist: ansys-tools-filetransfer>=0.1,<0.3
|
|
16
|
+
Requires-Dist: ansys-units>=0.3.3,<0.5
|
|
17
|
+
Requires-Dist: docker>=7.1.0
|
|
18
|
+
Requires-Dist: grpcio>=1.30.0
|
|
19
|
+
Requires-Dist: grpcio-health-checking>=1.30.0
|
|
20
|
+
Requires-Dist: grpcio-status>=1.30.0
|
|
21
|
+
Requires-Dist: lxml>=4.9.2
|
|
22
|
+
Requires-Dist: nltk>=3.9.1
|
|
23
|
+
Requires-Dist: numpy>=1.14.0,<3.0.0
|
|
24
|
+
Requires-Dist: pandas>=1.1.0,<2.3
|
|
25
|
+
Requires-Dist: pyyaml>=6.0
|
|
26
|
+
Requires-Dist: Sphinx==7.4.7 ; extra == "docs"
|
|
27
|
+
Requires-Dist: jupyter_sphinx==0.5.3 ; extra == "docs"
|
|
28
|
+
Requires-Dist: numpydoc==1.8.0 ; extra == "docs"
|
|
29
|
+
Requires-Dist: matplotlib==3.10.0 ; extra == "docs"
|
|
30
|
+
Requires-Dist: ansys-sphinx-theme==1.2.4 ; extra == "docs"
|
|
31
|
+
Requires-Dist: pypandoc==1.14 ; extra == "docs"
|
|
32
|
+
Requires-Dist: pytest-sphinx==0.6.3 ; extra == "docs"
|
|
33
|
+
Requires-Dist: sphinx-autobuild==2024.10.3 ; extra == "docs"
|
|
34
|
+
Requires-Dist: sphinx-autodoc-typehints==2.3.0 ; extra == "docs"
|
|
35
|
+
Requires-Dist: sphinx-copybutton==0.5.2 ; extra == "docs"
|
|
36
|
+
Requires-Dist: sphinx-gallery==0.18.0 ; extra == "docs"
|
|
37
|
+
Requires-Dist: sphinx-notfound-page==1.0.4 ; extra == "docs"
|
|
38
|
+
Requires-Dist: sphinxcontrib-websupport==2.0.0 ; extra == "docs"
|
|
39
|
+
Requires-Dist: sphinxemoji==0.3.1 ; extra == "docs"
|
|
40
|
+
Requires-Dist: sphinx-toggleprompt==0.5.2 ; extra == "docs"
|
|
41
|
+
Requires-Dist: autodocsumm==0.2.14 ; extra == "docs"
|
|
42
|
+
Requires-Dist: beautifulsoup4==4.12.3 ; extra == "docs"
|
|
43
|
+
Requires-Dist: openpyxl>=3.1.5 ; extra == "docs"
|
|
44
|
+
Requires-Dist: plotly>=5.22.0 ; extra == "docs"
|
|
45
|
+
Requires-Dist: python-pptx>=0.6.23 ; extra == "docs"
|
|
46
|
+
Requires-Dist: quarto-cli==1.6.39 ; extra == "docs"
|
|
47
|
+
Requires-Dist: pdf2image==1.17.0 ; extra == "docs"
|
|
48
|
+
Requires-Dist: seaborn>=0.13.2 ; extra == "docs"
|
|
49
|
+
Requires-Dist: tensorflow>=2.17.0 ; extra == "docs"
|
|
50
|
+
Requires-Dist: h5py==3.12.1 ; extra == "reader"
|
|
51
|
+
Requires-Dist: pytest==8.3.4 ; extra == "tests"
|
|
52
|
+
Requires-Dist: pytest-cov==6.0.0 ; extra == "tests"
|
|
53
|
+
Requires-Dist: pytest-mock==3.14.0 ; extra == "tests"
|
|
54
|
+
Requires-Dist: pytest-xdist==3.6.1 ; extra == "tests"
|
|
34
55
|
Project-URL: Documentation, https://fluent.docs.pyansys.com/
|
|
35
|
-
Project-URL: Repository, https://github.com/ansys/pyfluent
|
|
36
56
|
Project-URL: Source, https://github.com/ansys/pyfluent
|
|
37
57
|
Project-URL: Tracker, https://github.com/ansys/pyfluent/issues
|
|
38
|
-
|
|
58
|
+
Provides-Extra: docs
|
|
59
|
+
Provides-Extra: reader
|
|
60
|
+
Provides-Extra: tests
|
|
39
61
|
|
|
40
62
|
PyFluent
|
|
41
63
|
========
|