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,6 @@
1
+ """The top-level module of PyFluent providing solver-related functionality."""
2
+
3
+ try:
4
+ from ansys.fluent.core.generated.solver.settings_builtin import * # noqa: F401, F403
5
+ except (ImportError, AttributeError, SyntaxError):
6
+ pass
@@ -46,7 +46,6 @@ from typing import (
46
46
  )
47
47
  import warnings
48
48
  import weakref
49
- from zipimport import zipimporter
50
49
 
51
50
  import ansys.fluent.core as pyfluent
52
51
  from ansys.fluent.core.utils.fluent_version import FluentVersion
@@ -470,6 +469,8 @@ class Base:
470
469
  return nullcontext()
471
470
 
472
471
  def __eq__(self, other):
472
+ if not isinstance(other, self.__class__):
473
+ return False
473
474
  return self.flproxy == other.flproxy and self.path == other.path
474
475
 
475
476
 
@@ -1164,7 +1165,7 @@ class WildcardPath(Group):
1164
1165
  except KeyError as ex:
1165
1166
  raise AttributeError(
1166
1167
  allowed_name_error_message(
1167
- context=self._state_cls.__name__,
1168
+ context=self._state_cls._python_name,
1168
1169
  trial_name=name,
1169
1170
  allowed_values=self.get_active_child_names(),
1170
1171
  )
@@ -1365,7 +1366,7 @@ class NamedObject(SettingsBase[DictStateType], Generic[ChildTypeT]):
1365
1366
  )
1366
1367
  raise KeyError(
1367
1368
  allowed_name_error_message(
1368
- context=self.__class__.__name__,
1369
+ context=self.__class__._python_name,
1369
1370
  trial_name=name,
1370
1371
  allowed_values=self.get_object_names(),
1371
1372
  )
@@ -1672,7 +1673,7 @@ class BaseCommand(Action):
1672
1673
  command_name=self.python_name, value=value, kwargs=kwds
1673
1674
  )
1674
1675
  if (
1675
- self.obj_name == "create"
1676
+ self.obj_name in ["create", "make-a-copy"]
1676
1677
  and isinstance(self._parent, NamedObject)
1677
1678
  and ret in self._parent
1678
1679
  ):
@@ -1909,7 +1910,7 @@ class _NonCreatableNamedObjectMixin(
1909
1910
  else:
1910
1911
  raise KeyError(
1911
1912
  allowed_name_error_message(
1912
- context=self.__class__.__name__,
1913
+ context=self.__class__._python_name,
1913
1914
  trial_name=name,
1914
1915
  allowed_values=self.get_object_names(),
1915
1916
  )
@@ -2161,30 +2162,17 @@ def get_root(
2161
2162
  RuntimeError
2162
2163
  If hash values are inconsistent.
2163
2164
  """
2164
- from ansys.fluent.core import CODEGEN_OUTDIR, CODEGEN_ZIP_SETTINGS, utils
2165
+ from ansys.fluent.core import CODEGEN_OUTDIR, utils
2165
2166
 
2166
- if os.getenv("PYFLUENT_USE_OLD_SETTINGSGEN") != "1":
2167
- try:
2168
- settings = utils.load_module(
2169
- f"settings_{version}",
2170
- CODEGEN_OUTDIR / "solver" / f"settings_{version}.py",
2171
- )
2172
- root_cls = settings.root
2173
- except FileNotFoundError:
2174
- obj_info = flproxy.get_static_info()
2175
- root_cls, _ = get_cls("", obj_info, version=version)
2176
- else:
2177
- if CODEGEN_ZIP_SETTINGS:
2178
- importer = zipimporter(
2179
- str(CODEGEN_OUTDIR / "solver" / f"settings_{version}.zip")
2180
- )
2181
- settings = importer.load_module("settings")
2182
- else:
2183
- settings = utils.load_module(
2184
- f"settings_{version}",
2185
- CODEGEN_OUTDIR / "solver" / f"settings_{version}" / "__init__.py",
2186
- )
2167
+ try:
2168
+ settings = utils.load_module(
2169
+ f"settings_{version}",
2170
+ CODEGEN_OUTDIR / "solver" / f"settings_{version}.py",
2171
+ )
2187
2172
  root_cls = settings.root
2173
+ except FileNotFoundError:
2174
+ obj_info = flproxy.get_static_info()
2175
+ root_cls, _ = get_cls("", obj_info, version=version)
2188
2176
  root = root_cls()
2189
2177
  root.set_flproxy(flproxy)
2190
2178
  root._set_on_interrupt(interrupt)
@@ -123,6 +123,9 @@ def _validate_locn_list(locn_list, ctxt):
123
123
 
124
124
 
125
125
  def _locns(locns, ctxt):
126
+ if locns == []:
127
+ # Raising 'RuntimeError' instead of 'ValueError' to address a limitation in the server-side implementation.
128
+ raise RuntimeError("No locations specified.")
126
129
  locn_names_and_objs = _locn_names_and_objs(locns)
127
130
  locn_list = []
128
131
  for name, obj in locn_names_and_objs:
@@ -1,6 +1,6 @@
1
1
  """Data for for builtin setting classes."""
2
2
 
3
- from ansys.fluent.core import FluentVersion
3
+ from ansys.fluent.core.utils.fluent_version import FluentVersion
4
4
 
5
5
  # {<class name>: (<kind>, <path>)}
6
6
  DATA = {
@@ -66,12 +66,12 @@ class DatamodelEvents(StreamingService):
66
66
  elif response.HasField("commandAttributeChangedEventResponse"):
67
67
  value = response.commandAttributeChangedEventResponse.value
68
68
  cb[1](_convert_variant_to_value(value))
69
- elif (
70
- response.HasField("modifiedEventResponse")
71
- or response.HasField("deletedEventResponse")
72
- or response.HasField("affectedEventResponse")
73
- ):
69
+ elif response.HasField(
70
+ "modifiedEventResponse"
71
+ ) or response.HasField("affectedEventResponse"):
74
72
  cb[1](cb[0])
73
+ elif response.HasField("deletedEventResponse"):
74
+ cb[1]()
75
75
  elif response.HasField("commandExecutedEventResponse"):
76
76
  command = response.commandExecutedEventResponse.command
77
77
  args = _convert_variant_to_value(
@@ -1,5 +1,6 @@
1
1
  """Module for events management."""
2
2
 
3
+ from dataclasses import dataclass, field, fields
3
4
  from enum import Enum
4
5
  from functools import partial
5
6
  import inspect
@@ -7,11 +8,41 @@ import logging
7
8
  from typing import Callable, Generic, Literal, Type, TypeVar
8
9
  import warnings
9
10
 
11
+ from google.protobuf.json_format import MessageToDict
12
+
10
13
  from ansys.api.fluent.v0 import events_pb2 as EventsProtoModule
11
14
  from ansys.fluent.core.exceptions import InvalidArgument
12
15
  from ansys.fluent.core.streaming_services.streaming import StreamingService
13
16
  from ansys.fluent.core.warnings import PyFluentDeprecationWarning
14
17
 
18
+ __all__ = [
19
+ "EventsManager",
20
+ "Event",
21
+ "SolverEvent",
22
+ "MeshingEvent",
23
+ "TimestepStartedEventInfo",
24
+ "TimestepEndedEventInfo",
25
+ "IterationEndedEventInfo",
26
+ "CalculationsStartedEventInfo",
27
+ "CalculationsEndedEventInfo",
28
+ "CalculationsPausedEventInfo",
29
+ "CalculationsResumedEventInfo",
30
+ "AboutToLoadCaseEventInfo",
31
+ "CaseLoadedEventInfo",
32
+ "AboutToLoadDataEventInfo",
33
+ "DataLoadedEventInfo",
34
+ "AboutToInitializeSolutionEventInfo",
35
+ "SolutionInitializedEventInfo",
36
+ "ReportDefinitionUpdatedEventInfo",
37
+ "ReportPlotSetUpdatedEventInfo",
38
+ "ResidualPlotUpdatedEventInfo",
39
+ "SettingsClearedEventInfo",
40
+ "SolutionPausedEventInfo",
41
+ "ProgressUpdatedEventInfo",
42
+ "SolverTimeEstimateUpdatedEventInfo",
43
+ "FatalErrorEventInfo",
44
+ ]
45
+
15
46
  network_logger = logging.getLogger("pyfluent.networking")
16
47
 
17
48
 
@@ -70,6 +101,269 @@ class MeshingEvent(Enum):
70
101
  return _missing_for_events(cls, value)
71
102
 
72
103
 
104
+ class EventInfoBase:
105
+ """Base class for event information classes."""
106
+
107
+ derived_classes = {}
108
+
109
+ def __init_subclass__(cls, event, **kwargs):
110
+ super().__init_subclass__(**kwargs)
111
+ cls.derived_classes[event] = cls
112
+
113
+ def __post_init__(self):
114
+ for f in fields(self):
115
+ # Cast to the correct type
116
+ setattr(self, f.name, f.type(getattr(self, f.name)))
117
+
118
+ def __getattr__(self, name):
119
+ for f in fields(self):
120
+ if f.metadata.get("deprecated_name") == name:
121
+ warnings.warn(
122
+ f"'{name}' is deprecated. Use '{f.name}' instead.",
123
+ PyFluentDeprecationWarning,
124
+ )
125
+ return getattr(self, f.name)
126
+ return self.__getattribute__(name)
127
+
128
+
129
+ @dataclass
130
+ class TimestepStartedEventInfo(EventInfoBase, event=SolverEvent.TIMESTEP_STARTED):
131
+ """Information about the event triggered when a timestep is started.
132
+
133
+ Attributes
134
+ ----------
135
+ index : int
136
+ Timestep index.
137
+ size : float
138
+ Timestep size.
139
+ """
140
+
141
+ index: int
142
+ size: float
143
+
144
+
145
+ @dataclass
146
+ class TimestepEndedEventInfo(EventInfoBase, event=SolverEvent.TIMESTEP_ENDED):
147
+ """Information about the event triggered when a timestep is ended.
148
+
149
+ Attributes
150
+ ----------
151
+ index : int
152
+ Timestep index.
153
+ size : float
154
+ Timestep size.
155
+ """
156
+
157
+ index: int
158
+ size: float
159
+
160
+
161
+ @dataclass
162
+ class IterationEndedEventInfo(EventInfoBase, event=SolverEvent.ITERATION_ENDED):
163
+ """Information about the event triggered when an iteration is ended.
164
+
165
+ Attributes
166
+ ----------
167
+ index : int
168
+ Iteration index.
169
+ """
170
+
171
+ index: int
172
+
173
+
174
+ class CalculationsStartedEventInfo(
175
+ EventInfoBase, event=SolverEvent.CALCULATIONS_STARTED
176
+ ):
177
+ """Information about the event triggered when calculations are started."""
178
+
179
+
180
+ class CalculationsEndedEventInfo(EventInfoBase, event=SolverEvent.CALCULATIONS_ENDED):
181
+ """Information about the event triggered when calculations are ended."""
182
+
183
+
184
+ class CalculationsPausedEventInfo(EventInfoBase, event=SolverEvent.CALCULATIONS_PAUSED):
185
+ """Information about the event triggered when calculations are paused."""
186
+
187
+
188
+ class CalculationsResumedEventInfo(
189
+ EventInfoBase, event=SolverEvent.CALCULATIONS_RESUMED
190
+ ):
191
+ """Information about the event triggered when calculations are resumed."""
192
+
193
+
194
+ @dataclass
195
+ class AboutToLoadCaseEventInfo(EventInfoBase, event=SolverEvent.ABOUT_TO_LOAD_CASE):
196
+ """Information about the event triggered just before a case file is loaded.
197
+
198
+ Attributes
199
+ ----------
200
+ case_file_name : str
201
+ Case filename.
202
+ """
203
+
204
+ case_file_name: str = field(metadata=dict(deprecated_name="casefilepath"))
205
+
206
+
207
+ @dataclass
208
+ class CaseLoadedEventInfo(EventInfoBase, event=SolverEvent.CASE_LOADED):
209
+ """Information about the event triggered after a case file is loaded.
210
+
211
+ Attributes
212
+ ----------
213
+ case_file_name : str
214
+ Case filename.
215
+ """
216
+
217
+ case_file_name: str = field(metadata=dict(deprecated_name="casefilepath"))
218
+
219
+
220
+ @dataclass
221
+ class AboutToLoadDataEventInfo(EventInfoBase, event=SolverEvent.ABOUT_TO_LOAD_DATA):
222
+ """Information about the event triggered just before a data file is loaded.
223
+
224
+ Attributes
225
+ ----------
226
+ data_file_name : str
227
+ Data filename.
228
+ """
229
+
230
+ data_file_name: str = field(metadata=dict(deprecated_name="datafilepath"))
231
+
232
+
233
+ @dataclass
234
+ class DataLoadedEventInfo(EventInfoBase, event=SolverEvent.DATA_LOADED):
235
+ """Information about the event triggered after a data file is loaded.
236
+
237
+ Attributes
238
+ ----------
239
+ data_file_name : str
240
+ Data filename.
241
+ """
242
+
243
+ data_file_name: str = field(metadata=dict(deprecated_name="datafilepath"))
244
+
245
+
246
+ class AboutToInitializeSolutionEventInfo(
247
+ EventInfoBase, event=SolverEvent.ABOUT_TO_INITIALIZE_SOLUTION
248
+ ):
249
+ """Information about the event triggered just before solution is initialized."""
250
+
251
+
252
+ class SolutionInitializedEventInfo(
253
+ EventInfoBase, event=SolverEvent.SOLUTION_INITIALIZED
254
+ ):
255
+ """Information about the event triggered after solution is initialized."""
256
+
257
+
258
+ @dataclass
259
+ class ReportDefinitionUpdatedEventInfo(
260
+ EventInfoBase, event=SolverEvent.REPORT_DEFINITION_UPDATED
261
+ ):
262
+ """Information about the event triggered when a report definition is updated.
263
+
264
+ Attributes
265
+ ----------
266
+ report_name : str
267
+ Report name.
268
+ """
269
+
270
+ report_name: str = field(metadata=dict(deprecated_name="reportdefinitionname"))
271
+
272
+
273
+ @dataclass
274
+ class ReportPlotSetUpdatedEventInfo(
275
+ EventInfoBase, event=SolverEvent.REPORT_PLOT_SET_UPDATED
276
+ ):
277
+ """Information about the event triggered when a report plot set is updated.
278
+
279
+ Attributes
280
+ ----------
281
+ plot_set_name : str
282
+ Plot set name.
283
+ """
284
+
285
+ plot_set_name: str = field(metadata=dict(deprecated_name="plotsetname"))
286
+
287
+
288
+ class ResidualPlotUpdatedEventInfo(
289
+ EventInfoBase, event=SolverEvent.RESIDUAL_PLOT_UPDATED
290
+ ):
291
+ """Information about the event triggered when residual plots are updated."""
292
+
293
+
294
+ class SettingsClearedEventInfo(EventInfoBase, event=SolverEvent.SETTINGS_CLEARED):
295
+ """Information about the event triggered when settings are cleared."""
296
+
297
+
298
+ @dataclass
299
+ class SolutionPausedEventInfo(EventInfoBase, event=SolverEvent.SOLUTION_PAUSED):
300
+ """Information about the event triggered when solution is paused.
301
+
302
+ Attributes
303
+ ----------
304
+ level : str
305
+ Level of the pause event.
306
+ index : int
307
+ Index of the pause event.
308
+ """
309
+
310
+ level: str
311
+ index: int
312
+
313
+
314
+ @dataclass
315
+ class ProgressUpdatedEventInfo(EventInfoBase, event=SolverEvent.PROGRESS_UPDATED):
316
+ """Information about the event triggered when progress is updated.
317
+
318
+ Attributes
319
+ ----------
320
+ message : str
321
+ Progress message.
322
+ percentage : int
323
+ Progress percentage.
324
+ """
325
+
326
+ message: str
327
+ percentage: int = field(metadata=dict(deprecated_name="percentComplete"))
328
+
329
+
330
+ @dataclass
331
+ class SolverTimeEstimateUpdatedEventInfo(
332
+ EventInfoBase, event=SolverEvent.SOLVER_TIME_ESTIMATE_UPDATED
333
+ ):
334
+ """Information about the event triggered when solver time estimate is updated.
335
+
336
+ Attributes
337
+ ----------
338
+ hours : float
339
+ Hours of solver time estimate.
340
+ minutes : float
341
+ Minutes of solver time estimate.
342
+ seconds : float
343
+ Seconds of solver time estimate.
344
+ """
345
+
346
+ hours: float
347
+ minutes: float
348
+ seconds: float
349
+
350
+
351
+ @dataclass
352
+ class FatalErrorEventInfo(EventInfoBase, event=SolverEvent.FATAL_ERROR):
353
+ """Information about the event triggered when a fatal error occurs.
354
+
355
+ Attributes
356
+ ----------
357
+ message : str
358
+ Error message.
359
+ error_code : int
360
+ Error code.
361
+ """
362
+
363
+ message: str
364
+ error_code: int = field(metadata=dict(deprecated_name="errorCode"))
365
+
366
+
73
367
  TEvent = TypeVar("TEvent")
74
368
 
75
369
 
@@ -100,6 +394,17 @@ class EventsManager(Generic[TEvent]):
100
394
  self._session = session
101
395
  self._sync_event_ids = {}
102
396
 
397
+ def _construct_event_info(
398
+ self, response: EventsProtoModule.BeginStreamingResponse, event: TEvent
399
+ ):
400
+ event_info_msg = getattr(response, event.value.lower())
401
+ # Note: MessageToDict's parameter names are different in different protobuf versions
402
+ event_info_dict = MessageToDict(event_info_msg, True)
403
+ solver_event = SolverEvent(event.value)
404
+ event_info_cls = EventInfoBase.derived_classes.get(solver_event)
405
+ # Key names can be different, but their order is the same
406
+ return event_info_cls(*event_info_dict.values())
407
+
103
408
  def _process_streaming(
104
409
  self, service, id, stream_begin_method, started_evt, *args, **kwargs
105
410
  ):
@@ -129,30 +434,33 @@ class EventsManager(Generic[TEvent]):
129
434
  for callback in callbacks_map.values():
130
435
  callback(
131
436
  session=self._session,
132
- event_info=getattr(response, event_name.value.lower()),
437
+ event_info=self._construct_event_info(response, event_name),
133
438
  )
134
439
  except StopIteration:
135
440
  break
136
441
 
137
442
  @staticmethod
138
443
  def _make_callback_to_call(callback: Callable, args, kwargs):
139
- old_style = "session_id" in inspect.signature(callback).parameters
140
- if old_style:
444
+ params = inspect.signature(callback).parameters
445
+ if "session_id" in params:
141
446
  warnings.warn(
142
447
  "Update event callback function signatures"
143
448
  " substituting 'session' for 'session_id'.",
144
449
  PyFluentDeprecationWarning,
145
450
  )
146
- fn = partial(callback, *args, **kwargs)
147
- return (
148
- (
149
- lambda session, event_info: fn(
150
- session_id=session.id, event_info=event_info
151
- )
451
+ return lambda session, event_info: callback(
452
+ *args, session_id=session.id, event_info=event_info, **kwargs
453
+ )
454
+ else:
455
+ positional_args = [
456
+ p
457
+ for p in params
458
+ if p not in kwargs and p not in ("session", "event_info")
459
+ ]
460
+ kwargs.update(dict(zip(positional_args, args)))
461
+ return lambda session, event_info: callback(
462
+ session=session, event_info=event_info, **kwargs
152
463
  )
153
- if old_style
154
- else fn
155
- )
156
464
 
157
465
  def register_callback(
158
466
  self,
@@ -229,8 +537,8 @@ class EventsManager(Generic[TEvent]):
229
537
  del callbacks_map[callback_id]
230
538
  sync_event_id = self._sync_event_ids.pop(callback_id, None)
231
539
  if sync_event_id:
232
- self._session.scheme_eval.scheme_eval(
233
- f"(cancel-solution-monitor 'pyfluent-{sync_event_id})"
540
+ self._session._app_utilities.unregister_pause_on_solution_events(
541
+ registration_id=sync_event_id
234
542
  )
235
543
 
236
544
  def start(self, *args, **kwargs) -> None:
@@ -247,44 +555,20 @@ class EventsManager(Generic[TEvent]):
247
555
  callback_id: str,
248
556
  callback: Callable,
249
557
  ) -> tuple[Literal[SolverEvent.SOLUTION_PAUSED], Callable]:
250
- unique_id = self._session.scheme_eval.scheme_eval(
251
- f"""
252
- (let
253
- ((ids
254
- (let loop ((i 1))
255
- (define next-id (string->symbol (format #f "pyfluent-~d" i)))
256
- (if (check-monitor-existence next-id)
257
- (loop (1+ i))
258
- (list i next-id)
259
- )
260
- )
261
- ))
262
- (register-solution-monitor
263
- (cadr ids)
264
- (lambda (niter time)
265
- (if (integer? niter)
266
- (begin
267
- (events/transmit 'auto-pause (cons (car ids) niter))
268
- (grpcserver/auto-pause (is-server-running?) (cadr ids))
269
- )
270
- )
271
- ()
272
- )
273
- {'#t' if event_type == SolverEvent.TIMESTEP_ENDED else '#f'}
274
- )
275
- (car ids)
276
- )
277
- """
558
+ unique_id: int = self._session._app_utilities.register_pause_on_solution_events(
559
+ solution_event=event_type
278
560
  )
279
561
 
280
- def on_pause(session, event_info: EventsProtoModule.AutoPauseEvent):
281
- if unique_id == event_info.level:
282
- event_info_cls = (
283
- EventsProtoModule.TimestepEndedEvent
284
- if event_type == SolverEvent.TIMESTEP_ENDED
285
- else EventsProtoModule.IterationEndedEvent
286
- )
287
- event_info = event_info_cls(index=event_info.index)
562
+ def on_pause(session, event_info: SolutionPausedEventInfo):
563
+ if unique_id == int(event_info.level):
564
+ if event_type == SolverEvent.ITERATION_ENDED:
565
+ event_info = IterationEndedEventInfo(index=event_info.index)
566
+ else:
567
+ event_info = TimestepEndedEventInfo(
568
+ # TODO: Timestep size is currently not available
569
+ index=event_info.index,
570
+ size=0,
571
+ )
288
572
  try:
289
573
  callback(session, event_info)
290
574
  except Exception as e:
@@ -293,8 +577,8 @@ class EventsManager(Generic[TEvent]):
293
577
  exc_info=True,
294
578
  )
295
579
  finally:
296
- session.scheme_eval.scheme_eval(
297
- f"(grpcserver/auto-resume (is-server-running?) 'pyfluent-{unique_id})"
580
+ session._app_utilities.resume_on_solution_event(
581
+ registration_id=unique_id
298
582
  )
299
583
 
300
584
  self._sync_event_ids[callback_id] = unique_id
@@ -16,6 +16,8 @@ from ansys.fluent.core.examples.downloads import download_file
16
16
  from ansys.fluent.core.utils.file_transfer_service import RemoteFileTransferStrategy
17
17
  from ansys.fluent.core.utils.fluent_version import FluentVersion
18
18
 
19
+ sys.path.append(Path(__file__).parent / "util")
20
+
19
21
 
20
22
  def pytest_addoption(parser):
21
23
  parser.addoption(
@@ -281,6 +283,13 @@ def new_solver_session():
281
283
  solver.exit()
282
284
 
283
285
 
286
+ @pytest.fixture
287
+ def new_solver_session_t4():
288
+ solver = create_session(processor_count=4)
289
+ yield solver
290
+ solver.exit()
291
+
292
+
284
293
  @pytest.fixture
285
294
  def new_solver_session_sp():
286
295
  solver = create_session(precision="single")
@@ -327,6 +336,14 @@ def mixing_elbow_settings_session(new_solver_session):
327
336
  return solver
328
337
 
329
338
 
339
+ @pytest.fixture
340
+ def mixing_elbow_case_session_t4(new_solver_session_t4):
341
+ solver = new_solver_session_t4
342
+ case_name = download_file("mixing_elbow.cas.h5", "pyfluent/mixing_elbow")
343
+ solver.settings.file.read(file_type="case", file_name=case_name)
344
+ return solver
345
+
346
+
330
347
  @pytest.fixture
331
348
  def mixing_elbow_case_data_session(new_solver_session):
332
349
  solver = new_solver_session
@@ -383,3 +400,16 @@ def periodic_rot_settings_session(new_solver_session):
383
400
  @pytest.fixture
384
401
  def disable_datamodel_cache(monkeypatch: pytest.MonkeyPatch):
385
402
  monkeypatch.setattr(pyfluent, "DATAMODEL_USE_STATE_CACHE", False)
403
+
404
+
405
+ @pytest.fixture(params=["old", "new"])
406
+ def datamodel_api_version_all(request, monkeypatch: pytest.MonkeyPatch) -> None:
407
+ if request.param == "new":
408
+ monkeypatch.setenv("REMOTING_NEW_DM_API", "1")
409
+ monkeypatch.setenv("REMOTING_MAPPED_NEW_DM_API", "1")
410
+
411
+
412
+ @pytest.fixture
413
+ def datamodel_api_version_new(monkeypatch: pytest.MonkeyPatch) -> None:
414
+ monkeypatch.setenv("REMOTING_NEW_DM_API", "1")
415
+ monkeypatch.setenv("REMOTING_MAPPED_NEW_DM_API", "1")
@@ -4,7 +4,7 @@ import tempfile
4
4
  import pytest
5
5
 
6
6
  try:
7
- from ansys.fluent.core import (
7
+ from ansys.fluent.core.solver import (
8
8
  Ablation,
9
9
  Battery,
10
10
  BoundaryCondition,