ansys-fluent-core 0.28.dev0__py3-none-any.whl → 0.28.1__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 (63) hide show
  1. ansys/fluent/core/__init__.py +15 -16
  2. ansys/fluent/core/_version.py +1 -1
  3. ansys/fluent/core/codegen/allapigen.py +0 -3
  4. ansys/fluent/core/codegen/builtin_settingsgen.py +5 -20
  5. ansys/fluent/core/codegen/print_fluent_version.py +9 -14
  6. ansys/fluent/core/codegen/walk_api.py +57 -0
  7. ansys/fluent/core/fluent_connection.py +26 -22
  8. ansys/fluent/core/generated/api_tree/api_objects.json +1 -1
  9. ansys/fluent/core/generated/datamodel_252/meshing.py +21 -0
  10. ansys/fluent/core/generated/datamodel_252/preferences.py +7 -0
  11. ansys/fluent/core/generated/fluent_version_252.py +3 -3
  12. ansys/fluent/core/generated/meshing/tui_252.py +1183 -1133
  13. ansys/fluent/core/generated/solver/settings_252.py +8944 -6572
  14. ansys/fluent/core/generated/solver/settings_252.pyi +6357 -5352
  15. ansys/fluent/core/generated/solver/tui_252.py +3039 -2473
  16. ansys/fluent/core/journaling.py +4 -4
  17. ansys/fluent/core/launcher/fluent_container.py +31 -7
  18. ansys/fluent/core/launcher/launcher.py +3 -2
  19. ansys/fluent/core/launcher/launcher_utils.py +9 -0
  20. ansys/fluent/core/launcher/process_launch_string.py +8 -6
  21. ansys/fluent/core/launcher/pyfluent_enums.py +6 -3
  22. ansys/fluent/core/launcher/server_info.py +25 -2
  23. ansys/fluent/core/launcher/slurm_launcher.py +6 -3
  24. ansys/fluent/core/launcher/standalone_launcher.py +11 -9
  25. ansys/fluent/core/post_objects/post_helper.py +16 -10
  26. ansys/fluent/core/services/__init__.py +2 -0
  27. ansys/fluent/core/services/api_upgrade.py +11 -9
  28. ansys/fluent/core/services/app_utilities.py +408 -0
  29. ansys/fluent/core/services/datamodel_se.py +42 -5
  30. ansys/fluent/core/services/datamodel_tui.py +5 -2
  31. ansys/fluent/core/services/field_data.py +1 -0
  32. ansys/fluent/core/services/reduction.py +2 -0
  33. ansys/fluent/core/services/settings.py +5 -2
  34. ansys/fluent/core/session.py +27 -4
  35. ansys/fluent/core/session_pure_meshing.py +1 -1
  36. ansys/fluent/core/session_solver.py +0 -1
  37. ansys/fluent/core/solver/__init__.py +6 -0
  38. ansys/fluent/core/solver/flobject.py +15 -27
  39. ansys/fluent/core/solver/function/reduction.py +3 -0
  40. ansys/fluent/core/solver/settings_builtin_data.py +1 -1
  41. ansys/fluent/core/streaming_services/datamodel_event_streaming.py +5 -5
  42. ansys/fluent/core/streaming_services/events_streaming.py +336 -52
  43. ansys/fluent/tests/conftest.py +30 -0
  44. ansys/fluent/tests/test_builtin_settings.py +1 -1
  45. ansys/fluent/tests/test_codegen.py +0 -410
  46. ansys/fluent/tests/test_datamodel_api.py +449 -0
  47. ansys/fluent/tests/test_datamodel_service.py +64 -64
  48. ansys/fluent/tests/test_events_manager.py +24 -6
  49. ansys/fluent/tests/test_field_data.py +32 -0
  50. ansys/fluent/tests/test_launcher.py +30 -2
  51. ansys/fluent/tests/test_mapped_api.py +774 -0
  52. ansys/fluent/tests/test_reduction.py +30 -0
  53. ansys/fluent/tests/test_session.py +16 -1
  54. ansys/fluent/tests/test_settings_api.py +21 -0
  55. ansys/fluent/tests/test_solution_variables.py +27 -0
  56. ansys/fluent/tests/util/__init__.py +36 -0
  57. {ansys_fluent_core-0.28.dev0.dist-info → ansys_fluent_core-0.28.1.dist-info}/METADATA +4 -3
  58. {ansys_fluent_core-0.28.dev0.dist-info → ansys_fluent_core-0.28.1.dist-info}/RECORD +61 -58
  59. {ansys_fluent_core-0.28.dev0.dist-info → ansys_fluent_core-0.28.1.dist-info}/WHEEL +1 -1
  60. ansys/fluent/core/codegen/settingsgen_old.py +0 -535
  61. ansys/fluent/tests/fluent/test_version/test.py +0 -2
  62. {ansys_fluent_core-0.28.dev0.dist-info → ansys_fluent_core-0.28.1.dist-info}/AUTHORS +0 -0
  63. {ansys_fluent_core-0.28.dev0.dist-info → ansys_fluent_core-0.28.1.dist-info}/LICENSE +0 -0
@@ -0,0 +1,408 @@
1
+ """Wrappers over AppUtilities gRPC service of Fluent."""
2
+
3
+ from enum import Enum
4
+ from typing import List, Tuple
5
+
6
+ import grpc
7
+
8
+ from ansys.api.fluent.v0 import app_utilities_pb2 as AppUtilitiesProtoModule
9
+ from ansys.api.fluent.v0 import app_utilities_pb2_grpc as AppUtilitiesGrpcModule
10
+ from ansys.fluent.core.services.interceptors import (
11
+ BatchInterceptor,
12
+ ErrorStateInterceptor,
13
+ GrpcErrorInterceptor,
14
+ TracingInterceptor,
15
+ )
16
+ from ansys.fluent.core.streaming_services.events_streaming import SolverEvent
17
+
18
+
19
+ class AppUtilitiesService:
20
+ """AppUtilities Service."""
21
+
22
+ def __init__(
23
+ self, channel: grpc.Channel, metadata: List[Tuple[str, str]], fluent_error_state
24
+ ):
25
+ """__init__ method of AppUtilities class."""
26
+ intercept_channel = grpc.intercept_channel(
27
+ channel,
28
+ GrpcErrorInterceptor(),
29
+ ErrorStateInterceptor(fluent_error_state),
30
+ TracingInterceptor(),
31
+ BatchInterceptor(),
32
+ )
33
+ self._stub = AppUtilitiesGrpcModule.AppUtilitiesStub(intercept_channel)
34
+ self._metadata = metadata
35
+
36
+ def get_product_version(
37
+ self, request: AppUtilitiesProtoModule.GetProductVersionRequest
38
+ ) -> AppUtilitiesProtoModule.GetProductVersionResponse:
39
+ """Get product version RPC of AppUtilities service."""
40
+ return self._stub.GetProductVersion(request, metadata=self._metadata)
41
+
42
+ def get_build_info(
43
+ self, request: AppUtilitiesProtoModule.GetBuildInfoRequest
44
+ ) -> AppUtilitiesProtoModule.GetBuildInfoResponse:
45
+ """Get build info RPC of AppUtilities service."""
46
+ return self._stub.GetBuildInfo(request, metadata=self._metadata)
47
+
48
+ def get_controller_process_info(
49
+ self, request: AppUtilitiesProtoModule.GetControllerProcessInfoRequest
50
+ ) -> AppUtilitiesProtoModule.GetControllerProcessInfoResponse:
51
+ """Get controller process info RPC of AppUtilities service."""
52
+ return self._stub.GetControllerProcessInfo(request, metadata=self._metadata)
53
+
54
+ def get_solver_process_info(
55
+ self, request: AppUtilitiesProtoModule.GetSolverProcessInfoRequest
56
+ ) -> AppUtilitiesProtoModule.GetSolverProcessInfoResponse:
57
+ """Get solver process info RPC of AppUtilities service."""
58
+ return self._stub.GetSolverProcessInfo(request, metadata=self._metadata)
59
+
60
+ def get_app_mode(
61
+ self, request: AppUtilitiesProtoModule.GetAppModeRequest
62
+ ) -> AppUtilitiesProtoModule.GetAppModeResponse:
63
+ """Get app mode RPC of AppUtilities service."""
64
+ return self._stub.GetAppMode(request, metadata=self._metadata)
65
+
66
+ def start_python_journal(
67
+ self, request: AppUtilitiesProtoModule.StartPythonJournalRequest
68
+ ) -> AppUtilitiesProtoModule.StartPythonJournalResponse:
69
+ """Start python journal RPC of AppUtilities service."""
70
+ return self._stub.StartPythonJournal(request, metadata=self._metadata)
71
+
72
+ def stop_python_journal(
73
+ self, request: AppUtilitiesProtoModule.StopPythonJournalRequest
74
+ ) -> AppUtilitiesProtoModule.StopPythonJournalResponse:
75
+ """Stop python journal RPC of AppUtilities service."""
76
+ return self._stub.StopPythonJournal(request, metadata=self._metadata)
77
+
78
+ def is_beta_enabled(
79
+ self, request: AppUtilitiesProtoModule.IsBetaEnabledRequest
80
+ ) -> AppUtilitiesProtoModule.IsBetaEnabledResponse:
81
+ """Is beta enabled RPC of AppUtilities service."""
82
+ return self._stub.IsBetaEnabled(request, metadata=self._metadata)
83
+
84
+ def is_wildcard(
85
+ self, request: AppUtilitiesProtoModule.IsWildcardRequest
86
+ ) -> AppUtilitiesProtoModule.IsWildcardResponse:
87
+ """Is wildcard RPC of AppUtilities service."""
88
+ return self._stub.IsWildcard(request, metadata=self._metadata)
89
+
90
+ def is_solution_data_available(
91
+ self, request: AppUtilitiesProtoModule.IsSolutionDataAvailableRequest
92
+ ) -> AppUtilitiesProtoModule.IsSolutionDataAvailableResponse:
93
+ """Is solution data available RPC of AppUtilities service."""
94
+ return self._stub.IsSolutionDataAvailable(request, metadata=self._metadata)
95
+
96
+ def register_pause_on_solution_events(
97
+ self, request: AppUtilitiesProtoModule.RegisterPauseOnSolutionEventsRequest
98
+ ) -> AppUtilitiesProtoModule.RegisterPauseOnSolutionEventsResponse:
99
+ """Register on pause solution events RPC of AppUtilities service."""
100
+ return self._stub.RegisterPauseOnSolutionEvents(
101
+ request, metadata=self._metadata
102
+ )
103
+
104
+ def resume_on_solution_event(
105
+ self, request: AppUtilitiesProtoModule.ResumeOnSolutionEventRequest
106
+ ) -> AppUtilitiesProtoModule.ResumeOnSolutionEventResponse:
107
+ """Resume on solution event RPC of AppUtilities service."""
108
+ return self._stub.ResumeOnSolutionEvent(request, metadata=self._metadata)
109
+
110
+ def unregister_pause_on_solution_events(
111
+ self, request: AppUtilitiesProtoModule.UnregisterPauseOnSolutionEventsRequest
112
+ ) -> AppUtilitiesProtoModule.UnregisterPauseOnSolutionEventsResponse:
113
+ """Unregister on pause solution events RPC of AppUtilities service."""
114
+ return self._stub.UnregisterPauseOnSolutionEvents(
115
+ request, metadata=self._metadata
116
+ )
117
+
118
+ def exit(
119
+ self, request: AppUtilitiesProtoModule.ExitRequest
120
+ ) -> AppUtilitiesProtoModule.ExitResponse:
121
+ """Exit RPC of AppUtilities service."""
122
+ return self._stub.Exit(request, metadata=self._metadata)
123
+
124
+
125
+ class AppUtilitiesOld:
126
+ """AppUtilitiesOld."""
127
+
128
+ def __init__(self, scheme_eval):
129
+ """__init__ method of AppUtilitiesOld class."""
130
+ self.scheme_eval = scheme_eval
131
+
132
+ def get_product_version(self) -> str:
133
+ """Get product version."""
134
+ return self.scheme_eval.version
135
+
136
+ def get_build_info(self) -> dict:
137
+ """Get build info."""
138
+ build_time = self.scheme_eval.scheme_eval("(inquire-build-time)")
139
+ build_id = self.scheme_eval.scheme_eval("(inquire-build-id)")
140
+ vcs_revision = self.scheme_eval.scheme_eval("(inquire-src-vcs-id)")
141
+ vcs_branch = self.scheme_eval.scheme_eval("(inquire-src-vcs-branch)")
142
+ return {
143
+ "build_time": build_time,
144
+ "build_id": build_id,
145
+ "vcs_revision": vcs_revision,
146
+ "vcs_branch": vcs_branch,
147
+ }
148
+
149
+ def get_controller_process_info(self) -> dict:
150
+ """Get controller process info."""
151
+ cortex_host = self.scheme_eval.scheme_eval("(cx-cortex-host)")
152
+ cortex_pid = self.scheme_eval.scheme_eval("(cx-cortex-id)")
153
+ cortex_pwd = self.scheme_eval.scheme_eval("(cortex-pwd)")
154
+ return {
155
+ "hostname": cortex_host,
156
+ "process_id": cortex_pid,
157
+ "working_directory": cortex_pwd,
158
+ }
159
+
160
+ def get_solver_process_info(self) -> dict:
161
+ """Get solver process info."""
162
+ fluent_host = self.scheme_eval.scheme_eval("(cx-client-host)")
163
+ fluent_pid = self.scheme_eval.scheme_eval("(cx-client-id)")
164
+ fluent_pwd = self.scheme_eval.scheme_eval("(cx-send '(cx-client-pwd))")
165
+ return {
166
+ "hostname": fluent_host,
167
+ "process_id": fluent_pid,
168
+ "working_directory": fluent_pwd,
169
+ }
170
+
171
+ def get_app_mode(self) -> Enum:
172
+ """Get app mode."""
173
+ from ansys.fluent.core import FluentMode
174
+
175
+ if self.scheme_eval.scheme_eval("(cx-solver-mode?)"):
176
+ mode_str = self.scheme_eval.scheme_eval('(getenv "PRJAPP_APP")')
177
+ if mode_str == "flaero_server":
178
+ return FluentMode.SOLVER_AERO
179
+ elif mode_str == "flicing":
180
+ return FluentMode.SOLVER_ICING
181
+ else:
182
+ return FluentMode.SOLVER
183
+ else:
184
+ return FluentMode.MESHING
185
+
186
+ def start_python_journal(self, journal_name: str | None = None) -> int:
187
+ """Start python journal."""
188
+ if journal_name:
189
+ self.scheme_eval.exec([f'(api-start-python-journal "{journal_name}")'])
190
+ else:
191
+ self.scheme_eval.scheme_eval(
192
+ "(define pyfluent-journal-str-port (open-output-string))"
193
+ )
194
+ self.scheme_eval.scheme_eval(
195
+ "(api-echo-python-port pyfluent-journal-str-port)"
196
+ )
197
+ return "1"
198
+
199
+ def stop_python_journal(self, journal_id: str | None = None) -> str:
200
+ """Stop python journal."""
201
+ if journal_id:
202
+ self.scheme_eval.scheme_eval(
203
+ "(api-unecho-python-port pyfluent-journal-str-port)"
204
+ )
205
+ journal_str = self.scheme_eval.scheme_eval(
206
+ "(close-output-port pyfluent-journal-str-port)"
207
+ )
208
+ return journal_str
209
+ else:
210
+ self.scheme_eval.exec(["(api-stop-python-journal)"])
211
+
212
+ def is_beta_enabled(self) -> bool:
213
+ """Is beta enabled."""
214
+ return self.scheme_eval.scheme_eval("(is-beta-feature-available?)")
215
+
216
+ def is_wildcard(self, input: str | None = None) -> bool:
217
+ """Is wildcard."""
218
+ return self.scheme_eval.scheme_eval(f'(has-fnmatch-wild-card? "{input}")')
219
+
220
+ def is_solution_data_available(self) -> bool:
221
+ """Is solution data available."""
222
+ return self.scheme_eval.scheme_eval("(data-valid?)")
223
+
224
+ def register_pause_on_solution_events(self, solution_event: SolverEvent) -> int:
225
+ """Register pause on solution events."""
226
+ unique_id: int = self.scheme_eval.scheme_eval(
227
+ f"""
228
+ (let
229
+ ((ids
230
+ (let loop ((i 1))
231
+ (define next-id (string->symbol (format #f "pyfluent-~d" i)))
232
+ (if (check-monitor-existence next-id)
233
+ (loop (1+ i))
234
+ (list i next-id)
235
+ )
236
+ )
237
+ ))
238
+ (register-solution-monitor
239
+ (cadr ids)
240
+ (lambda (niter time)
241
+ (if (integer? niter)
242
+ (begin
243
+ (events/transmit 'auto-pause (cons (car ids) niter))
244
+ (grpcserver/auto-pause (is-server-running?) (cadr ids))
245
+ )
246
+ )
247
+ ()
248
+ )
249
+ {'#t' if solution_event == SolverEvent.TIMESTEP_ENDED else '#f'}
250
+ )
251
+ (car ids)
252
+ )
253
+ """
254
+ )
255
+ return unique_id
256
+
257
+ def resume_on_solution_event(self, registration_id: int) -> None:
258
+ """Resume on solution event."""
259
+ self.scheme_eval.scheme_eval(
260
+ f"(grpcserver/auto-resume (is-server-running?) 'pyfluent-{registration_id})"
261
+ )
262
+
263
+ def unregister_pause_on_solution_events(self, registration_id: int) -> None:
264
+ """Unregister pause on solution events."""
265
+ self.scheme_eval.scheme_eval(
266
+ f"(cancel-solution-monitor 'pyfluent-{registration_id})"
267
+ )
268
+
269
+ def exit(self) -> None:
270
+ """Exit."""
271
+ self.scheme_eval.exec(("(exit-server)",))
272
+
273
+
274
+ class AppUtilities:
275
+ """AppUtilities."""
276
+
277
+ def __init__(self, service: AppUtilitiesService):
278
+ """__init__ method of AppUtilities class."""
279
+ self.service = service
280
+
281
+ def get_product_version(self) -> str:
282
+ """Get product version."""
283
+ request = AppUtilitiesProtoModule.GetProductVersionRequest()
284
+ response = self.service.get_product_version(request)
285
+ return f"{response.major}.{response.minor}.{response.patch}"
286
+
287
+ def get_build_info(self) -> dict:
288
+ """Get build info."""
289
+ request = AppUtilitiesProtoModule.GetBuildInfoRequest()
290
+ response = self.service.get_build_info(request)
291
+ return {
292
+ "build_time": response.build_time,
293
+ "build_id": response.build_id,
294
+ "vcs_revision": response.vcs_revision,
295
+ "vcs_branch": response.vcs_branch,
296
+ }
297
+
298
+ def get_controller_process_info(self) -> dict:
299
+ """Get controller process info."""
300
+ request = AppUtilitiesProtoModule.GetControllerProcessInfoRequest()
301
+ response = self.service.get_controller_process_info(request)
302
+ return {
303
+ "hostname": response.hostname,
304
+ "process_id": response.process_id,
305
+ "working_directory": response.working_directory,
306
+ }
307
+
308
+ def get_solver_process_info(self) -> dict:
309
+ """Get solver process info."""
310
+ request = AppUtilitiesProtoModule.GetSolverProcessInfoRequest()
311
+ response = self.service.get_solver_process_info(request)
312
+ return {
313
+ "hostname": response.hostname,
314
+ "process_id": response.process_id,
315
+ "working_directory": response.working_directory,
316
+ }
317
+
318
+ def get_app_mode(self) -> Enum:
319
+ """Get app mode.
320
+
321
+ Raises
322
+ ------
323
+ ValueError
324
+ If app mode is unknown.
325
+ """
326
+ import ansys.fluent.core as pyfluent
327
+
328
+ request = AppUtilitiesProtoModule.GetAppModeRequest()
329
+ response = self.service.get_app_mode(request)
330
+ match response.app_mode:
331
+ case AppUtilitiesProtoModule.APP_MODE_UNKNOWN:
332
+ raise ValueError("Unknown app mode.")
333
+ case AppUtilitiesProtoModule.APP_MODE_MESHING:
334
+ return pyfluent.FluentMode.MESHING
335
+ case AppUtilitiesProtoModule.APP_MODE_SOLVER:
336
+ return pyfluent.FluentMode.SOLVER
337
+ case AppUtilitiesProtoModule.APP_MODE_SOLVER_ICING:
338
+ return pyfluent.FluentMode.SOLVER_ICING
339
+ case AppUtilitiesProtoModule.APP_MODE_SOLVER_AERO:
340
+ return pyfluent.FluentMode.SOLVER_AERO
341
+
342
+ def start_python_journal(self, journal_name: str | None = None) -> int:
343
+ """Start python journal."""
344
+ request = AppUtilitiesProtoModule.StartPythonJournalRequest()
345
+ if journal_name:
346
+ request.journal_name = journal_name
347
+ response = self.service.start_python_journal(request)
348
+ return response.journal_id
349
+
350
+ def stop_python_journal(self, journal_id: str | None = None) -> str:
351
+ """Stop python journal."""
352
+ request = AppUtilitiesProtoModule.StopPythonJournalRequest()
353
+ if journal_id:
354
+ request.journal_id = journal_id
355
+ response = self.service.stop_python_journal(request)
356
+ return response.journal_str
357
+
358
+ def is_beta_enabled(self) -> bool:
359
+ """Is beta enabled."""
360
+ request = AppUtilitiesProtoModule.IsBetaEnabledRequest()
361
+ response = self.service.is_beta_enabled(request)
362
+ return response.is_beta_enabled
363
+
364
+ def is_wildcard(self, input: str | None = None) -> bool:
365
+ """Is wildcard."""
366
+ request = AppUtilitiesProtoModule.IsWildcardRequest()
367
+ request.input = input
368
+ response = self.service.is_wildcard(request)
369
+ return response.is_wildcard
370
+
371
+ def is_solution_data_available(self) -> bool:
372
+ """Is solution data available."""
373
+ request = AppUtilitiesProtoModule.IsSolutionDataAvailableRequest()
374
+ response = self.service.is_solution_data_available(request)
375
+ return response.is_solution_data_available
376
+
377
+ def register_pause_on_solution_events(self, solution_event: SolverEvent) -> int:
378
+ """Register pause on solution events."""
379
+ request = AppUtilitiesProtoModule.RegisterPauseOnSolutionEventsRequest()
380
+ request.solution_event = AppUtilitiesProtoModule.SOLUTION_EVENT_UNKNOWN
381
+ match solution_event:
382
+ case SolverEvent.ITERATION_ENDED:
383
+ request.solution_event = (
384
+ AppUtilitiesProtoModule.SOLUTION_EVENT_ITERATION
385
+ )
386
+ case SolverEvent.TIMESTEP_ENDED:
387
+ request.solution_event = (
388
+ AppUtilitiesProtoModule.SOLUTION_EVENT_TIME_STEP
389
+ )
390
+ response = self.service.register_pause_on_solution_events(request)
391
+ return response.registration_id
392
+
393
+ def resume_on_solution_event(self, registration_id: int) -> None:
394
+ """Resume on solution event."""
395
+ request = AppUtilitiesProtoModule.ResumeOnSolutionEventRequest()
396
+ request.registration_id = registration_id
397
+ self.service.resume_on_solution_event(request)
398
+
399
+ def unregister_pause_on_solution_events(self, registration_id: int) -> None:
400
+ """Unregister pause on solution events."""
401
+ request = AppUtilitiesProtoModule.UnregisterPauseOnSolutionEventsRequest()
402
+ request.registration_id = registration_id
403
+ self.service.unregister_pause_on_solution_events(request)
404
+
405
+ def exit(self) -> None:
406
+ """Exit."""
407
+ request = AppUtilitiesProtoModule.ExitRequest()
408
+ self.service.exit(request)
@@ -807,7 +807,7 @@ class DatamodelService(StreamingService):
807
807
  self.event_streaming.register_callback(subscription.tag, obj, cb)
808
808
  return subscription
809
809
 
810
- def add_on_command_executed(
810
+ def add_on_command_executed_old(
811
811
  self, rules: str, path: str, command: str, obj, cb: Callable
812
812
  ) -> EventSubscription:
813
813
  """Add on command executed."""
@@ -826,6 +826,24 @@ class DatamodelService(StreamingService):
826
826
  self.event_streaming.register_callback(subscription.tag, obj, cb)
827
827
  return subscription
828
828
 
829
+ def add_on_command_executed(
830
+ self, rules: str, path: str, obj, cb: Callable
831
+ ) -> EventSubscription:
832
+ """Add on command executed."""
833
+ request_dict = {
834
+ "eventrequest": [
835
+ {
836
+ "rules": rules,
837
+ "commandExecutedEventRequest": {
838
+ "path": path,
839
+ },
840
+ }
841
+ ]
842
+ }
843
+ subscription = EventSubscription(self, path, request_dict)
844
+ self.event_streaming.register_callback(subscription.tag, obj, cb)
845
+ return subscription
846
+
829
847
  def add_on_attribute_changed(
830
848
  self, rules: str, path: str, attribute: str, obj, cb: Callable
831
849
  ) -> EventSubscription:
@@ -1326,13 +1344,15 @@ class PyMenu(PyStateContainer):
1326
1344
  self.rules, convert_path_to_se_path(self.path), child_type, self, cb
1327
1345
  )
1328
1346
 
1329
- def add_on_command_executed(self, command: str, cb: Callable) -> EventSubscription:
1347
+ def add_on_command_executed_old(
1348
+ self, command: str, cb: Callable
1349
+ ) -> EventSubscription:
1330
1350
  """Register a callback for when a command is executed.
1331
1351
 
1332
1352
  Parameters
1333
1353
  ----------
1334
1354
  command : str
1335
- command name
1355
+ Command name
1336
1356
  cb : Callable
1337
1357
  Callback function
1338
1358
 
@@ -1341,10 +1361,27 @@ class PyMenu(PyStateContainer):
1341
1361
  EventSubscription
1342
1362
  EventSubscription instance which can be used to unregister the callback
1343
1363
  """
1344
- return self.service.add_on_command_executed(
1364
+ return self.service.add_on_command_executed_old(
1345
1365
  self.rules, convert_path_to_se_path(self.path), command, self, cb
1346
1366
  )
1347
1367
 
1368
+ def add_on_command_executed(self, cb: Callable) -> EventSubscription:
1369
+ """Register a callback for when a command is executed.
1370
+
1371
+ Parameters
1372
+ ----------
1373
+ cb : Callable
1374
+ Callback function
1375
+
1376
+ Returns
1377
+ -------
1378
+ EventSubscription
1379
+ EventSubscription instance which can be used to unregister the callback
1380
+ """
1381
+ return self.service.add_on_command_executed(
1382
+ self.rules, convert_path_to_se_path(self.path), self, cb
1383
+ )
1384
+
1348
1385
 
1349
1386
  class PyParameter(PyStateContainer):
1350
1387
  """Object class using StateEngine based DatamodelService as backend.
@@ -1577,7 +1614,7 @@ class PyNamedObjectContainer:
1577
1614
  # On-deleted subscription objects are unsubscribed after the datamodel
1578
1615
  # object is deleted.
1579
1616
  self[key].add_on_deleted(
1580
- lambda _: self.service.subscriptions.unsubscribe_while_deleting(
1617
+ lambda: self.service.subscriptions.unsubscribe_while_deleting(
1581
1618
  self.rules, se_path, "after"
1582
1619
  )
1583
1620
  )
@@ -125,10 +125,12 @@ class DatamodelService:
125
125
  channel: grpc.Channel,
126
126
  metadata: list[tuple[str, str]],
127
127
  fluent_error_state,
128
+ app_utilities,
128
129
  scheme_eval,
129
130
  ) -> None:
130
131
  """__init__ method of DatamodelService class."""
131
132
  self._impl = DatamodelServiceImpl(channel, metadata, fluent_error_state)
133
+ self._app_utilities = app_utilities
132
134
  self._scheme_eval = scheme_eval
133
135
 
134
136
  def get_attribute_value(
@@ -170,7 +172,8 @@ class DatamodelService:
170
172
  request = DataModelProtoModule.GetStaticInfoRequest()
171
173
  request.path = path
172
174
  response = self._impl.get_static_info(request)
173
- return MessageToDict(response.info, including_default_value_fields=True)
175
+ # Note: MessageToDict's parameter names are different in different protobuf versions
176
+ return MessageToDict(response.info, True)
174
177
 
175
178
 
176
179
  class PyMenu:
@@ -233,7 +236,7 @@ class PyMenu:
233
236
  Query result (any Python datatype)
234
237
  """
235
238
  with ApiUpgradeAdvisor(
236
- self._service._scheme_eval,
239
+ self._service._app_utilities,
237
240
  self._version,
238
241
  self._mode,
239
242
  ):
@@ -153,6 +153,7 @@ class FieldInfo:
153
153
  "display_name": field_info.displayName,
154
154
  "section": field_info.section,
155
155
  "domain": field_info.domain,
156
+ "quantity_name": field_info.quantity_name,
156
157
  }
157
158
  for field_info in response.fieldInfo
158
159
  }
@@ -263,6 +263,8 @@ class Reduction:
263
263
  raise ValueError(f"Invalid location input: '{loc}'")
264
264
 
265
265
  def _get_location_string(self, locations, ctxt) -> List[str]:
266
+ if locations == []:
267
+ return []
266
268
  for loc in locations:
267
269
  if isinstance(loc, str):
268
270
  self._validate_str_location(loc)
@@ -136,9 +136,12 @@ def _get_request_instance_for_path(request_class, path: str) -> Any:
136
136
  class SettingsService:
137
137
  """Service for accessing and modifying Fluent settings."""
138
138
 
139
- def __init__(self, channel, metadata, scheme_eval, fluent_error_state) -> None:
139
+ def __init__(
140
+ self, channel, metadata, app_utilities, scheme_eval, fluent_error_state
141
+ ) -> None:
140
142
  """__init__ method of SettingsService class."""
141
143
  self._service_impl = _SettingsServiceImpl(channel, metadata, fluent_error_state)
144
+ self._app_utilities = app_utilities
142
145
  self._scheme_eval = scheme_eval
143
146
 
144
147
  @_trace
@@ -369,7 +372,7 @@ class SettingsService:
369
372
  """Checks whether a name has a wildcard pattern."""
370
373
  return self._scheme_eval.is_defined(
371
374
  "has-fnmatch-wild-card?"
372
- ) and self._scheme_eval.scheme_eval(f'(has-fnmatch-wild-card? "{name}")')
375
+ ) and self._app_utilities.is_wildcard(name)
373
376
 
374
377
  @_trace
375
378
  def is_interactive_mode(self) -> bool:
@@ -10,6 +10,7 @@ import weakref
10
10
  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
+ from ansys.fluent.core.services.app_utilities import AppUtilitiesOld
13
14
  from ansys.fluent.core.services.field_data import FieldDataService
14
15
  from ansys.fluent.core.services.scheme_eval import SchemeEval
15
16
  from ansys.fluent.core.streaming_services.datamodel_event_streaming import (
@@ -52,6 +53,17 @@ class _IsDataValid:
52
53
  return self._scheme_eval.scheme_eval("(data-valid?)")
53
54
 
54
55
 
56
+ class _AppUtilitiesFactory:
57
+ """AppUtilities factory."""
58
+
59
+ @staticmethod
60
+ def _create_app_utilities(scheme_eval, fluent_connection):
61
+ if FluentVersion(scheme_eval.version) < FluentVersion.v252:
62
+ return AppUtilitiesOld(scheme_eval)
63
+ else:
64
+ return fluent_connection._connection_interface._app_utilities
65
+
66
+
55
67
  class BaseSession:
56
68
  """Encapsulates a Fluent session.
57
69
 
@@ -124,7 +136,6 @@ class BaseSession:
124
136
  self.scheme_eval = scheme_eval
125
137
  self.rp_vars = RPVars(self.scheme_eval.string_eval)
126
138
  self._preferences = None
127
- self.journal = Journal(self.scheme_eval)
128
139
 
129
140
  self._transcript_service = service_creator("transcript").create(
130
141
  fluent_connection._channel, fluent_connection._metadata
@@ -133,10 +144,17 @@ class BaseSession:
133
144
  if self._start_transcript:
134
145
  self.transcript.start()
135
146
 
147
+ self._app_utilities = _AppUtilitiesFactory._create_app_utilities(
148
+ self.scheme_eval, self._fluent_connection
149
+ )
150
+
151
+ self.journal = Journal(self._app_utilities)
152
+
136
153
  self._datamodel_service_tui = service_creator("tui").create(
137
154
  fluent_connection._channel,
138
155
  fluent_connection._metadata,
139
156
  self._error_state,
157
+ self._app_utilities,
140
158
  self.scheme_eval,
141
159
  )
142
160
 
@@ -175,13 +193,17 @@ class BaseSession:
175
193
 
176
194
  def __init__(self, _session):
177
195
  """Initialize Fields."""
196
+ self._is_solution_data_valid = (
197
+ _session._app_utilities.is_solution_data_available
198
+ )
178
199
  self.field_info = service_creator("field_info").create(
179
- _session._field_data_service, _IsDataValid(_session.scheme_eval)
200
+ _session._field_data_service,
201
+ self._is_solution_data_valid,
180
202
  )
181
203
  self.field_data = service_creator("field_data").create(
182
204
  _session._field_data_service,
183
205
  self.field_info,
184
- _IsDataValid(_session.scheme_eval),
206
+ self._is_solution_data_valid,
185
207
  _session.scheme_eval,
186
208
  )
187
209
  self.field_data_streaming = FieldDataStreaming(
@@ -190,7 +212,7 @@ class BaseSession:
190
212
  self.field_data_old = service_creator("field_data_old").create(
191
213
  _session._field_data_service,
192
214
  self.field_info,
193
- _IsDataValid(_session.scheme_eval),
215
+ self._is_solution_data_valid,
194
216
  _session.scheme_eval,
195
217
  )
196
218
 
@@ -199,6 +221,7 @@ class BaseSession:
199
221
  self._settings_service = service_creator("settings").create(
200
222
  fluent_connection._channel,
201
223
  fluent_connection._metadata,
224
+ self._app_utilities,
202
225
  self.scheme_eval,
203
226
  self._error_state,
204
227
  )
@@ -156,7 +156,7 @@ class PureMeshing(BaseSession):
156
156
  RuntimeError
157
157
  If beta features are not enabled in Fluent.
158
158
  """
159
- if not self.scheme_eval.scheme_eval("(is-beta-feature-available?)"):
159
+ if not self._app_utilities.is_beta_enabled():
160
160
  raise RuntimeError("Topology-based Meshing is a beta feature in Fluent.")
161
161
  self._base_meshing.topology_based_meshing_workflow.initialize()
162
162
  return self._base_meshing.topology_based_meshing_workflow
@@ -117,7 +117,6 @@ class Solver(BaseSession):
117
117
  ):
118
118
  self._tui_service = self._datamodel_service_tui
119
119
  self._se_service = self._datamodel_service_se
120
- self._settings_service = self._settings_service
121
120
  self._tui = None
122
121
  self._workflow = None
123
122
  self._system_coupling = None