ansys-fluent-core 0.27.dev1__py3-none-any.whl → 0.28.dev0__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.

Files changed (188) hide show
  1. ansys/fluent/core/__init__.py +22 -9
  2. ansys/fluent/core/_version.py +5 -2
  3. ansys/fluent/core/codegen/__init__.py +0 -3
  4. ansys/fluent/core/codegen/allapigen.py +1 -5
  5. ansys/fluent/core/codegen/builtin_settingsgen.py +44 -10
  6. ansys/fluent/core/codegen/datamodelgen.py +53 -12
  7. ansys/fluent/core/codegen/settingsgen.py +21 -12
  8. ansys/fluent/core/codegen/settingsgen_old.py +2 -2
  9. ansys/fluent/core/codegen/tuigen.py +1 -1
  10. ansys/fluent/core/codegen/write_settings_yaml.py +3 -4
  11. ansys/fluent/core/data_model_cache.py +132 -70
  12. ansys/fluent/core/docs/README.rst +2 -2
  13. ansys/fluent/core/examples/downloads.py +3 -5
  14. ansys/fluent/core/exceptions.py +1 -0
  15. ansys/fluent/core/file_session.py +59 -131
  16. ansys/fluent/core/filereader/case_file.py +17 -17
  17. ansys/fluent/core/filereader/casereader.py +2 -1
  18. ansys/fluent/core/filereader/data_file.py +7 -7
  19. ansys/fluent/core/filereader/lispy.py +6 -1
  20. ansys/fluent/core/fluent_connection.py +35 -7
  21. ansys/fluent/core/generated/api_tree/api_objects.json +1 -1
  22. ansys/fluent/core/generated/datamodel_222/PMFileManagement.py +2 -2
  23. ansys/fluent/core/generated/datamodel_222/PartManagement.py +28 -28
  24. ansys/fluent/core/generated/datamodel_222/meshing.py +301 -301
  25. ansys/fluent/core/generated/datamodel_222/workflow.py +9 -9
  26. ansys/fluent/core/generated/datamodel_231/PMFileManagement.py +2 -2
  27. ansys/fluent/core/generated/datamodel_231/PartManagement.py +55 -55
  28. ansys/fluent/core/generated/datamodel_231/flicing.py +51 -51
  29. ansys/fluent/core/generated/datamodel_231/meshing.py +317 -317
  30. ansys/fluent/core/generated/datamodel_231/solverworkflow.py +51 -51
  31. ansys/fluent/core/generated/datamodel_231/workflow.py +9 -9
  32. ansys/fluent/core/generated/datamodel_232/PMFileManagement.py +2 -2
  33. ansys/fluent/core/generated/datamodel_232/PartManagement.py +55 -55
  34. ansys/fluent/core/generated/datamodel_232/flicing.py +51 -51
  35. ansys/fluent/core/generated/datamodel_232/meshing.py +335 -335
  36. ansys/fluent/core/generated/datamodel_232/solverworkflow.py +58 -58
  37. ansys/fluent/core/generated/datamodel_232/workflow.py +9 -9
  38. ansys/fluent/core/generated/datamodel_241/PMFileManagement.py +2 -2
  39. ansys/fluent/core/generated/datamodel_241/PartManagement.py +57 -57
  40. ansys/fluent/core/generated/datamodel_241/flicing.py +51 -51
  41. ansys/fluent/core/generated/datamodel_241/meshing.py +361 -361
  42. ansys/fluent/core/generated/datamodel_241/solverworkflow.py +58 -58
  43. ansys/fluent/core/generated/datamodel_241/workflow.py +9 -9
  44. ansys/fluent/core/generated/datamodel_242/MeshingUtilities.py +240 -240
  45. ansys/fluent/core/generated/datamodel_242/PMFileManagement.py +2 -2
  46. ansys/fluent/core/generated/datamodel_242/PartManagement.py +60 -60
  47. ansys/fluent/core/generated/datamodel_242/flicing.py +51 -51
  48. ansys/fluent/core/generated/datamodel_242/meshing.py +371 -371
  49. ansys/fluent/core/generated/datamodel_242/solverworkflow.py +58 -58
  50. ansys/fluent/core/generated/datamodel_242/workflow.py +9 -9
  51. ansys/fluent/core/generated/datamodel_251/MeshingUtilities.py +244 -244
  52. ansys/fluent/core/generated/datamodel_251/PMFileManagement.py +2 -2
  53. ansys/fluent/core/generated/datamodel_251/PartManagement.py +60 -60
  54. ansys/fluent/core/generated/datamodel_251/flicing.py +51 -51
  55. ansys/fluent/core/generated/datamodel_251/meshing.py +384 -382
  56. ansys/fluent/core/generated/datamodel_251/preferences.py +7 -0
  57. ansys/fluent/core/generated/datamodel_251/solverworkflow.py +58 -58
  58. ansys/fluent/core/generated/datamodel_251/workflow.py +10 -10
  59. ansys/fluent/core/generated/datamodel_252/MeshingUtilities.py +3664 -0
  60. ansys/fluent/core/generated/datamodel_252/PMFileManagement.py +288 -0
  61. ansys/fluent/core/generated/datamodel_252/PartManagement.py +2588 -0
  62. ansys/fluent/core/generated/datamodel_252/flicing.py +7972 -0
  63. ansys/fluent/core/generated/datamodel_252/meshing.py +2644 -0
  64. ansys/fluent/core/generated/datamodel_252/preferences.py +2760 -0
  65. ansys/fluent/core/generated/datamodel_252/solverworkflow.py +479 -0
  66. ansys/fluent/core/generated/datamodel_252/workflow.py +466 -0
  67. ansys/fluent/core/generated/fluent_version_251.py +4 -4
  68. ansys/fluent/core/generated/fluent_version_252.py +5 -0
  69. ansys/fluent/core/generated/meshing/tui_251.py +1139 -1179
  70. ansys/fluent/core/generated/meshing/tui_252.py +10181 -0
  71. ansys/fluent/core/generated/solver/settings_222.py +3 -3
  72. ansys/fluent/core/generated/solver/settings_231.py +4 -4
  73. ansys/fluent/core/generated/solver/settings_232.py +5 -5
  74. ansys/fluent/core/generated/solver/settings_241.py +5 -5
  75. ansys/fluent/core/generated/solver/settings_242.py +1185 -1185
  76. ansys/fluent/core/generated/solver/settings_251.py +1847 -1652
  77. ansys/fluent/core/generated/solver/settings_251.pyi +237 -211
  78. ansys/fluent/core/generated/solver/settings_252.py +90369 -0
  79. ansys/fluent/core/generated/solver/settings_252.pyi +63778 -0
  80. ansys/fluent/core/generated/solver/settings_builtin.py +612 -1
  81. ansys/fluent/core/generated/solver/settings_builtin.pyi +235 -0
  82. ansys/fluent/core/generated/solver/tui_251.py +2283 -2103
  83. ansys/fluent/core/generated/solver/tui_252.py +37720 -0
  84. ansys/fluent/core/journaling.py +1 -1
  85. ansys/fluent/core/launcher/error_handler.py +3 -0
  86. ansys/fluent/core/launcher/fluent_container.py +5 -0
  87. ansys/fluent/core/launcher/launcher.py +1 -2
  88. ansys/fluent/core/launcher/launcher_utils.py +17 -6
  89. ansys/fluent/core/launcher/process_launch_string.py +3 -3
  90. ansys/fluent/core/launcher/pyfluent_enums.py +1 -1
  91. ansys/fluent/core/launcher/slurm_launcher.py +2 -1
  92. ansys/fluent/core/launcher/standalone_launcher.py +11 -5
  93. ansys/fluent/core/launcher/watchdog.py +1 -1
  94. ansys/fluent/core/launcher/watchdog_exec +6 -3
  95. ansys/fluent/core/logging.py +1 -5
  96. ansys/fluent/core/parametric.py +6 -3
  97. ansys/fluent/core/post_objects/meta.py +1 -39
  98. ansys/fluent/core/post_objects/post_helper.py +4 -3
  99. ansys/fluent/core/post_objects/post_object_definitions.py +12 -7
  100. ansys/fluent/core/post_objects/post_objects_container.py +39 -2
  101. ansys/fluent/core/rpvars.py +2 -1
  102. ansys/fluent/core/scheduler/machine_list.py +3 -1
  103. ansys/fluent/core/search.py +109 -262
  104. ansys/fluent/core/services/__init__.py +3 -0
  105. ansys/fluent/core/services/api_upgrade.py +1 -0
  106. ansys/fluent/core/services/batch_ops.py +3 -1
  107. ansys/fluent/core/services/datamodel_se.py +37 -30
  108. ansys/fluent/core/services/datamodel_tui.py +8 -3
  109. ansys/fluent/core/services/deprecated_field_data.py +691 -0
  110. ansys/fluent/core/services/field_data.py +67 -357
  111. ansys/fluent/core/services/interceptors.py +6 -4
  112. ansys/fluent/core/services/reduction.py +1 -2
  113. ansys/fluent/core/services/scheme_eval.py +2 -3
  114. ansys/fluent/core/services/solution_variables.py +46 -48
  115. ansys/fluent/core/session.py +6 -4
  116. ansys/fluent/core/session_meshing.pyi +5 -0
  117. ansys/fluent/core/session_pure_meshing.pyi +4 -1
  118. ansys/fluent/core/session_solver_lite.py +2 -1
  119. ansys/fluent/core/solver/flobject.py +179 -207
  120. ansys/fluent/core/solver/flunits.py +65 -56
  121. ansys/fluent/core/solver/function/reduction.py +9 -29
  122. ansys/fluent/core/solver/settings_builtin_bases.py +28 -22
  123. ansys/fluent/core/solver/settings_builtin_data.py +105 -1
  124. ansys/fluent/core/solver/settings_external.py +0 -28
  125. ansys/fluent/core/streaming_services/field_data_streaming.py +1 -0
  126. ansys/fluent/core/streaming_services/monitor_streaming.py +0 -1
  127. ansys/fluent/core/systemcoupling.py +145 -14
  128. ansys/fluent/core/utils/__init__.py +18 -2
  129. ansys/fluent/core/utils/dump_session_data.py +7 -4
  130. ansys/fluent/core/utils/execution.py +2 -2
  131. ansys/fluent/core/utils/file_transfer_service.py +37 -42
  132. ansys/fluent/core/utils/fluent_version.py +20 -2
  133. ansys/fluent/core/utils/networking.py +39 -1
  134. ansys/fluent/core/workflow.py +3 -15
  135. ansys/fluent/tests/conftest.py +89 -7
  136. ansys/fluent/tests/fluent/test_version/test.py +2 -0
  137. ansys/fluent/tests/fluent_fixtures.py +195 -0
  138. ansys/fluent/tests/integration/test_optislang/test_optislang_integration.py +7 -7
  139. ansys/fluent/tests/parametric/test_parametric_workflow.py +14 -4
  140. ansys/fluent/tests/test_builtin_settings.py +28 -0
  141. ansys/fluent/tests/test_cad_to_post_ftm.py +1 -3
  142. ansys/fluent/tests/test_cad_to_post_wtm.py +1 -1
  143. ansys/fluent/tests/test_casereader.py +1 -1
  144. ansys/fluent/tests/test_codegen.py +116 -6
  145. ansys/fluent/tests/test_data_model_cache.py +1 -1
  146. ansys/fluent/tests/test_datamodel_service.py +14 -19
  147. ansys/fluent/tests/test_field_data.py +93 -45
  148. ansys/fluent/tests/test_file_session.py +32 -29
  149. ansys/fluent/tests/test_flobject.py +16 -58
  150. ansys/fluent/tests/test_fluent_fixes.py +5 -5
  151. ansys/fluent/tests/test_fluent_session.py +11 -8
  152. ansys/fluent/tests/test_fluent_version.py +1 -1
  153. ansys/fluent/tests/test_launcher.py +22 -5
  154. ansys/fluent/tests/test_launcher_remote.py +80 -4
  155. ansys/fluent/tests/test_meshing_utilities.py +93 -44
  156. ansys/fluent/tests/test_meshing_workflow.py +6 -6
  157. ansys/fluent/tests/test_meshingmode/test_meshing_launch.py +1 -1
  158. ansys/fluent/tests/test_new_meshing_workflow.py +42 -3
  159. ansys/fluent/tests/test_preferences.py +6 -6
  160. ansys/fluent/tests/test_reduction.py +61 -30
  161. ansys/fluent/tests/test_rp_vars.py +1 -1
  162. ansys/fluent/tests/test_search.py +53 -200
  163. ansys/fluent/tests/test_session.py +18 -13
  164. ansys/fluent/tests/test_settings_api.py +93 -29
  165. ansys/fluent/tests/test_settings_reader.py +1 -1
  166. ansys/fluent/tests/test_solver_monitors.py +1 -1
  167. ansys/fluent/tests/test_solvermode/test_calculationactivities.py +4 -4
  168. ansys/fluent/tests/test_solvermode/test_controls.py +3 -3
  169. ansys/fluent/tests/test_solvermode/test_methods.py +1 -1
  170. ansys/fluent/tests/test_solvermode/test_models.py +3 -3
  171. ansys/fluent/tests/test_systemcoupling.py +33 -5
  172. ansys/fluent/tests/test_topy.py +2 -2
  173. ansys/fluent/tests/test_tui_api.py +5 -5
  174. ansys/fluent/tests/test_utils.py +1 -1
  175. {ansys_fluent_core-0.27.dev1.dist-info → ansys_fluent_core-0.28.dev0.dist-info}/METADATA +6 -17
  176. ansys_fluent_core-0.28.dev0.dist-info/RECORD +291 -0
  177. ansys/fluent/core/generated/api_tree_222.pickle +0 -0
  178. ansys/fluent/core/generated/api_tree_231.pickle +0 -0
  179. ansys/fluent/core/generated/api_tree_232.pickle +0 -0
  180. ansys/fluent/core/generated/api_tree_241.pickle +0 -0
  181. ansys/fluent/core/generated/api_tree_242.pickle +0 -0
  182. ansys/fluent/core/generated/api_tree_251.pickle +0 -0
  183. ansys/fluent/tests/test_tests_util.py +0 -47
  184. ansys/fluent/tests/util/__init__.py +0 -38
  185. ansys_fluent_core-0.27.dev1.dist-info/RECORD +0 -283
  186. {ansys_fluent_core-0.27.dev1.dist-info → ansys_fluent_core-0.28.dev0.dist-info}/AUTHORS +0 -0
  187. {ansys_fluent_core-0.27.dev1.dist-info → ansys_fluent_core-0.28.dev0.dist-info}/LICENSE +0 -0
  188. {ansys_fluent_core-0.27.dev1.dist-info → ansys_fluent_core-0.28.dev0.dist-info}/WHEEL +0 -0
@@ -1,8 +1,5 @@
1
1
  """Miscellaneous utility functions."""
2
2
 
3
- import os
4
- import re
5
-
6
3
 
7
4
  def expand_api_file_argument(command_name, value, kwargs):
8
5
  """Expand API file argument."""
@@ -14,28 +11,3 @@ def expand_api_file_argument(command_name, value, kwargs):
14
11
  return [value, data_file]
15
12
  else:
16
13
  return [value]
17
-
18
-
19
- def use_search(codegen_outdir: str, version: str):
20
- """Whether to use ``_search()`` in the error handling.
21
-
22
- Parameters
23
- ----------
24
- codegen_outdir: str
25
- Codegen directory.
26
- version: str
27
- Fluent version.
28
- """
29
- fluent_version_str = version
30
- fluent_version_int = int(fluent_version_str.replace(".", "")[0:3])
31
- api_tree_files = [
32
- file for file in os.listdir(codegen_outdir) if file.endswith("pickle")
33
- ]
34
- api_tree_file_versions = [
35
- int(re.findall(r"\d+", file)[0]) for file in api_tree_files
36
- ]
37
- latest_api_tree_version = max(api_tree_file_versions)
38
- if len(api_tree_files) == 1 and fluent_version_int == latest_api_tree_version:
39
- return True
40
- else:
41
- return False
@@ -19,6 +19,7 @@ class FieldDataStreaming(StreamingService):
19
19
  """
20
20
 
21
21
  def __init__(self, session_id: str, service):
22
+ """Initialize FieldDataStreaming."""
22
23
  super().__init__(
23
24
  stream_begin_method="BeginFieldsStreaming",
24
25
  target=FieldDataStreaming._process_streaming,
@@ -188,7 +188,6 @@ class MonitorsManager(StreamingService):
188
188
  try:
189
189
  data_received = {}
190
190
  response = next(responses)
191
- x_axis_type = response.xaxisdata.xaxistype
192
191
  x_axis_index = response.xaxisdata.xaxisindex
193
192
  data_received["xvalues"] = x_axis_index
194
193
  for y_axis_value in response.yaxisvalues:
@@ -38,21 +38,31 @@ class SystemCoupling:
38
38
 
39
39
  Methods
40
40
  -------
41
- __getattr__
42
- get_variables
43
- get_regions
44
- get_analysis_type
45
- connect
46
- solve
41
+ get_variables()
42
+ Get variables
43
+ get_regions()
44
+ Get regions
45
+ get_analysis_type()
46
+ Get analysis type
47
+ connect()
48
+ Connect parallelly
49
+ solve()
50
+ Initialize and solve
47
51
  """
48
52
 
49
53
  def __init__(self, solver):
54
+ """Initialize SystemCoupling."""
50
55
  self._solver = solver
51
56
  # version check - this requires Fluent 2024 R1 or newer.
52
57
  if self._solver.get_fluent_version() < FluentVersion.v241:
53
58
  raise RuntimeError(
54
59
  f"Using {str(self._solver.get_fluent_version())}. PySystemCoupling integration requires {str(FluentVersion.v241)} or later."
55
60
  )
61
+ if self._solver.get_fluent_version() >= FluentVersion.v251:
62
+ # enable feature to be able to make System Coupling settings APIs calls
63
+ self._solver.scheme_eval.scheme_eval(
64
+ "(enable-feature 'sc/participant-info)"
65
+ )
56
66
 
57
67
  @property
58
68
  def participant_type(self) -> str:
@@ -61,36 +71,157 @@ class SystemCoupling:
61
71
 
62
72
  def get_variables(self) -> List[Variable]:
63
73
  """Get variables."""
64
- return self.__get_syc_setup()["variables"]
74
+
75
+ if self._solver.get_fluent_version() >= FluentVersion.v251:
76
+ variables = list()
77
+ region_names = (
78
+ self._solver.settings.setup.models.system_coupling.get_all_regions()
79
+ )
80
+ variable_names = set()
81
+ for region_name in region_names:
82
+ in_var_names = self._get_list(
83
+ self._solver.settings.setup.models.system_coupling.get_input_vars(
84
+ region_name=region_name
85
+ )
86
+ )
87
+ out_var_names = self._get_list(
88
+ self._solver.settings.setup.models.system_coupling.get_output_vars(
89
+ region_name=region_name
90
+ )
91
+ )
92
+ variable_names.update(in_var_names)
93
+ variable_names.update(out_var_names)
94
+ variable_names = sorted(list(variable_names))
95
+ for variable_name in variable_names:
96
+ variables.append(
97
+ Variable(
98
+ name=variable_name,
99
+ display_name=self._get_display_name(variable_name),
100
+ tensor_type=self._solver.settings.setup.models.system_coupling.get_tensor_type(
101
+ variable_name=variable_name
102
+ ),
103
+ is_extensive=self._solver.settings.setup.models.system_coupling.is_extensive_var(
104
+ variable_name=variable_name
105
+ ),
106
+ location=self._solver.settings.setup.models.system_coupling.get_data_location(
107
+ variable_name=variable_name
108
+ ),
109
+ quantity_type=self._get_quantity_type(variable_name),
110
+ )
111
+ )
112
+ return variables
113
+ else:
114
+ # maintains back-compatibility for 24.1 and 24.2
115
+ return self.__get_syc_setup()["variables"]
65
116
 
66
117
  def get_regions(self) -> List[Region]:
67
118
  """Get regions."""
68
- return self.__get_syc_setup()["regions"]
119
+
120
+ if self._solver.get_fluent_version() >= FluentVersion.v251:
121
+ region_names = (
122
+ self._solver.settings.setup.models.system_coupling.get_all_regions()
123
+ )
124
+ regions = list()
125
+ for region_name in region_names:
126
+ regions.append(
127
+ Region(
128
+ name=region_name,
129
+ display_name=self._get_display_name(region_name),
130
+ topology=self._solver.settings.setup.models.system_coupling.get_topology(
131
+ region_name=region_name
132
+ ),
133
+ input_variables=self._get_list(
134
+ self._solver.settings.setup.models.system_coupling.get_input_vars(
135
+ region_name=region_name
136
+ )
137
+ ),
138
+ output_variables=self._get_list(
139
+ self._solver.settings.setup.models.system_coupling.get_output_vars(
140
+ region_name=region_name
141
+ )
142
+ ),
143
+ )
144
+ )
145
+ return regions
146
+ else:
147
+ # maintains back-compatibility for 24.1 and 24.2
148
+ return self.__get_syc_setup()["regions"]
69
149
 
70
150
  def get_analysis_type(self) -> str:
71
151
  """Get analysis type."""
72
- return self.__get_syc_setup()["analysis-type"]
152
+ if self._solver.get_fluent_version() >= FluentVersion.v251:
153
+ return (
154
+ self._solver.settings.setup.models.system_coupling.get_analysis_type()
155
+ )
156
+ else:
157
+ # maintains back-compatibility for 24.1 and 24.2
158
+ return self.__get_syc_setup()["analysis-type"]
73
159
 
74
160
  def connect(self, host: str, port: int, name: str) -> None:
75
- """Connect parallelly."""
76
- self._solver.setup.models.system_coupling.connect_parallel(
161
+ """Connect to System Coupling."""
162
+ self._solver.settings.setup.models.system_coupling.connect_parallel(
77
163
  schost=host, scport=port, scname=name
78
164
  )
79
165
 
80
166
  def solve(self) -> None:
81
167
  """Initialize and solve."""
82
- self._solver.setup.models.system_coupling.init_and_solve()
168
+ self._solver.settings.setup.models.system_coupling.init_and_solve()
169
+
170
+ @staticmethod
171
+ def _get_quantity_type(variable_name: str) -> str:
172
+ """
173
+ For some variables, System Coupling should know the quantity type.
174
+ """
175
+ if variable_name in {"force", "lorentz-force"}:
176
+ return "Force"
177
+ elif variable_name in {"heatflow", "heatrate"}:
178
+ return "Heat Rate"
179
+ elif variable_name == "displacement":
180
+ return "Incremental Displacement"
181
+ elif variable_name == "temperature":
182
+ return "Temperature"
183
+ elif variable_name == "heat-transfer-coefficient":
184
+ return "Heat Transfer Coefficient"
185
+ elif variable_name == "near-wall-temperature":
186
+ return "Convection Reference Temperature"
187
+ elif variable_name == "electrical-conductivity":
188
+ return "Electrical Conductivity"
189
+ else:
190
+ return "Unspecified"
191
+
192
+ @staticmethod
193
+ def _get_display_name(internal_name: str) -> str:
194
+ """
195
+ Display names should not contain dashes.
196
+ """
197
+ return internal_name.replace("-", " ")
198
+
199
+ @staticmethod
200
+ def _get_list(value: list | None) -> list:
201
+ if isinstance(value, list):
202
+ return value
203
+ elif value is None:
204
+ return list()
205
+ raise TypeError(f"_get_list unexpected type of {value}")
83
206
 
84
207
  def __get_syc_setup(self) -> dict:
208
+ """
209
+ This function is for backward-compatibility reasons for 24.1 and 24.2 versions.
210
+ It tells Fluent to write the SCP file and then parses it to get the setup
211
+ information. The SCP file is then deleted.
212
+ With newer versions, settings APIs can be used directly, without having
213
+ to write the SCP file at all.
214
+ """
215
+
85
216
  def get_scp_string() -> str:
86
217
  """Get the SCP file contents in the form of an XML string."""
87
218
 
88
219
  scp_file_name = "fluent.scp"
89
- self._solver.setup.models.system_coupling.write_scp_file(
220
+ self._solver.settings.setup.models.system_coupling.write_scp_file(
90
221
  file_name=scp_file_name
91
222
  )
92
223
 
93
- if self._solver._fluent_connection._remote_instance != None:
224
+ if self._solver._fluent_connection._remote_instance is not None:
94
225
  # download the file locally in case Fluent is remote
95
226
  # assume file transfer service is configured - download the file
96
227
  self._solver.download(scp_file_name)
@@ -2,11 +2,12 @@
2
2
 
3
3
  import importlib.util
4
4
  import logging
5
+ from pathlib import Path
5
6
  import sys
6
7
 
7
- logger = logging.getLogger("pyfluent.general")
8
+ from ansys.fluent.core.search import search # noqa: F401
8
9
 
9
- from ansys.fluent.core.search import _search # noqa: F401
10
+ logger = logging.getLogger("pyfluent.general")
10
11
 
11
12
 
12
13
  def load_module(module_name, file_path):
@@ -17,3 +18,18 @@ def load_module(module_name, file_path):
17
18
  spec.loader.exec_module(module)
18
19
  logger.info(f"Loaded module {module_name} from {file_path}")
19
20
  return module
21
+
22
+
23
+ def get_examples_download_dir():
24
+ """Return the path to the examples download directory."""
25
+ parent_path = Path.home() / "Downloads"
26
+ parent_path.mkdir(exist_ok=True)
27
+ return parent_path / "ansys_fluent_core_examples"
28
+
29
+
30
+ def get_user_data_dir():
31
+ """Return the path to the user data directory."""
32
+ if sys.platform == "win32":
33
+ return Path.home() / "AppData" / "Local" / "Ansys" / "ansys_fluent_core"
34
+ else:
35
+ return Path.home() / ".local" / "share" / "Ansys" / "ansys_fluent_core"
@@ -104,6 +104,7 @@ class DumpDataReader:
104
104
  """Reads dump data."""
105
105
 
106
106
  def __init__(self, file_name: str):
107
+ """Initialize DumpDataReader."""
107
108
  with open(
108
109
  str(Path(file_name).resolve()),
109
110
  "rb",
@@ -114,7 +115,7 @@ class DumpDataReader:
114
115
  """Get session data."""
115
116
  return self._session_data
116
117
 
117
- def get_surface_data(self, surface_ids, data_types) -> list[np.array | None]:
118
+ def get_surface_data(self, surface_ids, data_types) -> list[np.ndarray | None]:
118
119
  """Get surface data."""
119
120
  tag_id = (("type", "surface-data"),)
120
121
 
@@ -130,7 +131,7 @@ class DumpDataReader:
130
131
 
131
132
  def get_scalar_field_data(
132
133
  self, surface_ids, data_location, provide_boundary_values, field_names
133
- ) -> list[np.array | None]:
134
+ ) -> list[np.ndarray | None]:
134
135
  """Get scalar field data."""
135
136
  tag_id = (
136
137
  ("type", "scalar-field"),
@@ -146,7 +147,9 @@ class DumpDataReader:
146
147
 
147
148
  return scalar_field_data
148
149
 
149
- def get_vector_field_data(self, surface_ids, field_names) -> list[np.array | None]:
150
+ def get_vector_field_data(
151
+ self, surface_ids, field_names
152
+ ) -> list[np.ndarray | None]:
150
153
  """Get vector field data."""
151
154
  tag_id = (("type", "vector-field"),)
152
155
 
@@ -163,7 +166,7 @@ class DumpDataReader:
163
166
 
164
167
  def get_pathlines_data(
165
168
  self, surface_ids, field_names, key
166
- ) -> list[np.array | None]:
169
+ ) -> list[np.ndarray | None]:
167
170
  """Get pathlines data."""
168
171
  pathlines_data = []
169
172
  for surface_id in surface_ids:
@@ -33,8 +33,8 @@ def asynchronous(f: Callable) -> Callable:
33
33
  >>> asynchronous_solve(solver_session_1, 100).result()
34
34
  >>> asynchronous(solver_session_2.tui.solve.iterate)(100).result()
35
35
 
36
- .. _Future: https://docs.python.org/3/library/asyncio-future.html#future-object # noqa: E501
37
- .. _result(): https://docs.python.org/3/library/asyncio-future.html#asyncio.Future.result # noqa: E501
36
+ .. _Future: https://docs.python.org/3/library/asyncio-future.html#future-object
37
+ .. _result(): https://docs.python.org/3/library/asyncio-future.html#asyncio.Future.result
38
38
  """
39
39
 
40
40
  @functools.wraps(f)
@@ -1,32 +1,26 @@
1
1
  """Provides a module for file transfer service."""
2
2
 
3
- import logging
4
3
  import os
5
4
  import pathlib
6
5
  import random
7
6
  import shutil
8
- from typing import Any, Callable, List, Protocol # noqa: F401
7
+ from typing import Any, Protocol
9
8
  import warnings
10
9
 
11
- import platformdirs
12
-
10
+ from ansys.fluent.core.utils import get_user_data_dir
13
11
  from ansys.fluent.core.utils.deprecate import deprecate_argument
14
12
  from ansys.fluent.core.warnings import PyFluentUserWarning
15
13
  import ansys.platform.instancemanagement as pypim
16
14
 
17
- logger = logging.getLogger("pyfluent.file_transfer_service")
18
-
19
-
20
15
  # Host path which is mounted to the file-transfer-service container
21
- MOUNT_SOURCE = platformdirs.user_data_dir(
22
- appname="ansys_fluent_core", appauthor="Ansys"
23
- )
16
+ MOUNT_SOURCE = str(get_user_data_dir())
24
17
 
25
18
 
26
19
  class PyPIMConfigurationError(ConnectionError):
27
20
  """Raised when `PyPIM<https://pypim.docs.pyansys.com/version/stable/>` is not configured."""
28
21
 
29
22
  def __init__(self):
23
+ """Initialize PyPIMConfigurationError."""
30
24
  super().__init__("PyPIM is not configured.")
31
25
 
32
26
 
@@ -394,6 +388,13 @@ class PimFileTransferService:
394
388
  """
395
389
 
396
390
  def __init__(self, pim_instance: Any | None = None):
391
+ """Initialize PimFileTransferService.
392
+
393
+ Parameters
394
+ ----------
395
+ pim_instance: Any, optional
396
+ PIM instance.
397
+ """
397
398
  self.pim_instance = pim_instance
398
399
  self.upload_server = None
399
400
  self.file_service = None
@@ -482,23 +483,20 @@ class PimFileTransferService:
482
483
  """
483
484
  files = [file_name] if isinstance(file_name, str) else file_name
484
485
  if self.is_configured():
485
- from alive_progress import alive_bar
486
-
487
- with alive_bar(len(files), title="Uploading...") as bar:
488
- for file in files:
489
- if os.path.isfile(file):
490
- if not self.file_service.file_exist(os.path.basename(file)):
491
- self.upload_file(
492
- file_name=file, remote_file_name=remote_file_name
493
- )
494
- bar()
495
- else:
496
- warnings.warn(
497
- f"\n{file} with the same name exists at the remote location.\n",
498
- PyFluentUserWarning,
499
- )
500
- elif not self.file_service.file_exist(os.path.basename(file)):
501
- raise FileNotFoundError(f"{file} does not exist.")
486
+ for file in files:
487
+ if os.path.isfile(file):
488
+ if not self.file_service.file_exist(os.path.basename(file)):
489
+ self.upload_file(
490
+ file_name=file, remote_file_name=remote_file_name
491
+ )
492
+ print(f"\n{os.path.basename(file_name)} uploaded.\n")
493
+ else:
494
+ warnings.warn(
495
+ f"\n{file} with the same name exists at the remote location.\n",
496
+ PyFluentUserWarning,
497
+ )
498
+ elif not self.file_service.file_exist(os.path.basename(file)):
499
+ raise FileNotFoundError(f"{file} does not exist.")
502
500
 
503
501
  def download_file(self, file_name: str, local_directory: str | None = None):
504
502
  """Download a file from the server supported by `PyPIM<https://pypim.docs.pyansys.com/version/stable/>`.
@@ -537,21 +535,18 @@ class PimFileTransferService:
537
535
  """
538
536
  files = [file_name] if isinstance(file_name, str) else file_name
539
537
  if self.is_configured():
540
- from alive_progress import alive_bar
541
-
542
- with alive_bar(len(files), title="Downloading...") as bar:
543
- for file in files:
544
- if os.path.isfile(file):
545
- warnings.warn(
546
- f"\nFile already exists. File path:\n{file}\n",
547
- PyFluentUserWarning,
548
- )
549
- else:
550
- self.download_file(
551
- file_name=os.path.basename(file),
552
- local_directory=local_directory,
553
- )
554
- bar()
538
+ for file in files:
539
+ if os.path.isfile(file):
540
+ warnings.warn(
541
+ f"\nFile already exists. File path:\n{file}\n",
542
+ PyFluentUserWarning,
543
+ )
544
+ else:
545
+ self.download_file(
546
+ file_name=os.path.basename(file),
547
+ local_directory=local_directory,
548
+ )
549
+ print(f"\n{os.path.basename(file_name)} downloaded.\n")
555
550
 
556
551
  def __call__(self, pim_instance: Any | None = None):
557
552
  self.pim_instance = pim_instance
@@ -5,7 +5,7 @@ from functools import total_ordering
5
5
  import os
6
6
 
7
7
  import ansys.fluent.core as pyfluent
8
- from ansys.fluent.core._version import fluent_release_version
8
+ from ansys.fluent.core._version import fluent_dev_version, fluent_release_version
9
9
 
10
10
 
11
11
  class AnsysVersionNotFound(RuntimeError):
@@ -18,8 +18,9 @@ class ComparisonError(RuntimeError):
18
18
  """Raised when a comparison can't be completed."""
19
19
 
20
20
  def __init__(self):
21
+ """Initialize ComparisonError."""
21
22
  super().__init__(
22
- f"Comparison operations are only supported between two members of 'FluentVersion'."
23
+ "Comparison operations are only supported between two members of 'FluentVersion'."
23
24
  )
24
25
 
25
26
 
@@ -52,6 +53,7 @@ class FluentVersion(Enum):
52
53
  FluentVersion.v232.awp_var == 'AWP_ROOT232'
53
54
  """
54
55
 
56
+ v252 = "25.2.0"
55
57
  v251 = "25.1.0"
56
58
  v242 = "24.2.0"
57
59
  v241 = "24.1.0"
@@ -109,6 +111,17 @@ class FluentVersion(Enum):
109
111
  """
110
112
  return cls(fluent_release_version)
111
113
 
114
+ @classmethod
115
+ def current_dev(cls):
116
+ """Return the version member of the current development version.
117
+
118
+ Returns
119
+ -------
120
+ FluentVersion
121
+ FluentVersion member corresponding to the latest development version.
122
+ """
123
+ return cls(fluent_dev_version)
124
+
112
125
  @property
113
126
  def awp_var(self):
114
127
  """Get the Fluent version in AWP environment variable format."""
@@ -119,6 +132,11 @@ class FluentVersion(Enum):
119
132
  """Get the Fluent version as a plain integer."""
120
133
  return int(self.value.replace(".", "")[:-1])
121
134
 
135
+ @property
136
+ def docker_image_tag(self):
137
+ """Get the Fluent version as a Docker image tag."""
138
+ return f"v{self.value}"
139
+
122
140
  def __lt__(self, other):
123
141
  if isinstance(other, FluentVersion):
124
142
  return self.value < other.value
@@ -4,6 +4,7 @@ from concurrent import futures
4
4
  import logging
5
5
  import socket
6
6
  from typing import Any
7
+ import urllib.request
7
8
 
8
9
  import grpc
9
10
  from grpc_health.v1 import health_pb2, health_pb2_grpc
@@ -68,7 +69,7 @@ def find_remoting_ip() -> str:
68
69
  ip = addrinfo[-1][0]
69
70
  port = get_free_port()
70
71
  address = f"{ip}:{port}"
71
- with _GrpcServer(address) as server:
72
+ with _GrpcServer(address):
72
73
  with grpc.insecure_channel(address) as channel:
73
74
  stub = health_pb2_grpc.HealthStub(channel)
74
75
  try:
@@ -83,3 +84,40 @@ def find_remoting_ip() -> str:
83
84
  return ip
84
85
  except Exception:
85
86
  network_logger.debug(f"Cannot use {ip} as remoting ip")
87
+
88
+
89
+ def check_url_exists(url: str) -> bool:
90
+ """Check if a URL exists.
91
+
92
+ Parameters
93
+ ----------
94
+ url : str
95
+ URL to check
96
+
97
+ Returns
98
+ -------
99
+ bool
100
+ True if the URL exists, False otherwise
101
+ """
102
+ try:
103
+ with urllib.request.urlopen(url) as response:
104
+ return response.status == 200
105
+ except Exception:
106
+ return False
107
+
108
+
109
+ def get_url_content(url: str) -> str:
110
+ """Get the content of a URL.
111
+
112
+ Parameters
113
+ ----------
114
+ url : str
115
+ URL to get content from
116
+
117
+ Returns
118
+ -------
119
+ str
120
+ content of the URL
121
+ """
122
+ with urllib.request.urlopen(url) as response:
123
+ return response.read()
@@ -24,6 +24,7 @@ class CommandInstanceCreationError(RuntimeError):
24
24
  """Raised when an attempt to create an instance of a task command fails."""
25
25
 
26
26
  def __init__(self, task_name):
27
+ """Initialize CommandInstanceCreationError."""
27
28
  super().__init__(f"Could not create command instance for task {task_name}.")
28
29
 
29
30
 
@@ -223,19 +224,6 @@ class BaseTask:
223
224
  attr="requiredInputs", other_attr="outputs"
224
225
  )
225
226
 
226
- def get_direct_upstream_tasks(self) -> list:
227
- """Get the list of tasks upstream of this one and directly connected by a data
228
- dependency.
229
-
230
- Returns
231
- -------
232
- list
233
- Upstream task list.
234
- """
235
- return self._tasks_with_matching_attributes(
236
- attr="requiredInputs", other_attr="outputs"
237
- )
238
-
239
227
  def get_direct_downstream_tasks(self) -> list:
240
228
  """Get the list of tasks downstream of this one and directly connected by a data
241
229
  dependency.
@@ -631,7 +619,7 @@ class TaskContainer(PyCallableStateObject):
631
619
  Iterator[BaseTask]
632
620
  Iterator of child objects.
633
621
  """
634
- for name in self._get_child_object_display_names():
622
+ for name in self.get_object_names():
635
623
  yield self[name]
636
624
 
637
625
  def __getitem__(self, name):
@@ -987,7 +975,7 @@ class CommandTask(BaseTask):
987
975
 
988
976
  def _cmd_sub_items_read_only(self, cmd, cmd_state):
989
977
  for key, value in cmd_state.items():
990
- if type(value) == dict:
978
+ if isinstance(value, dict):
991
979
  setattr(
992
980
  cmd, key, self._cmd_sub_items_read_only(getattr(cmd, key), value)
993
981
  )