ansys-fluent-core 0.34.2__py3-none-any.whl → 0.35.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.

Files changed (82) hide show
  1. ansys/fluent/core/__init__.py +48 -84
  2. ansys/fluent/core/codegen/allapigen.py +2 -2
  3. ansys/fluent/core/codegen/builtin_settingsgen.py +54 -28
  4. ansys/fluent/core/codegen/datamodelgen.py +3 -1
  5. ansys/fluent/core/codegen/print_fluent_version.py +2 -2
  6. ansys/fluent/core/codegen/settingsgen.py +4 -1
  7. ansys/fluent/core/codegen/tuigen.py +4 -4
  8. ansys/fluent/core/data_model_cache.py +2 -2
  9. ansys/fluent/core/docker/docker_compose.py +8 -9
  10. ansys/fluent/core/docker/utils.py +2 -2
  11. ansys/fluent/core/examples/downloads.py +8 -11
  12. ansys/fluent/core/fluent_connection.py +23 -15
  13. ansys/fluent/core/generated/api_tree/api_objects.json +1 -1
  14. ansys/fluent/core/generated/datamodel_231/flicing.py +50 -50
  15. ansys/fluent/core/generated/datamodel_231/meshing.py +182 -182
  16. ansys/fluent/core/generated/datamodel_232/flicing.py +45 -45
  17. ansys/fluent/core/generated/datamodel_232/meshing.py +172 -172
  18. ansys/fluent/core/generated/datamodel_241/flicing.py +45 -45
  19. ansys/fluent/core/generated/datamodel_241/meshing.py +303 -303
  20. ansys/fluent/core/generated/datamodel_242/flicing.py +50 -50
  21. ansys/fluent/core/generated/datamodel_242/meshing.py +309 -309
  22. ansys/fluent/core/generated/datamodel_242/part_management.py +3 -3
  23. ansys/fluent/core/generated/datamodel_251/flicing.py +50 -50
  24. ansys/fluent/core/generated/datamodel_251/meshing.py +327 -327
  25. ansys/fluent/core/generated/datamodel_251/part_management.py +9 -9
  26. ansys/fluent/core/generated/datamodel_252/flicing.py +30 -30
  27. ansys/fluent/core/generated/datamodel_252/meshing.py +370 -370
  28. ansys/fluent/core/generated/datamodel_252/part_management.py +15 -15
  29. ansys/fluent/core/generated/datamodel_261/flicing.py +35 -35
  30. ansys/fluent/core/generated/datamodel_261/meshing.py +444 -388
  31. ansys/fluent/core/generated/datamodel_261/part_management.py +5 -5
  32. ansys/fluent/core/generated/datamodel_261/preferences.py +28 -0
  33. ansys/fluent/core/generated/fluent_version_261.py +3 -3
  34. ansys/fluent/core/generated/meshing/tui_261.py +1247 -1136
  35. ansys/fluent/core/generated/solver/settings_261.py +9912 -4184
  36. ansys/fluent/core/generated/solver/settings_261.pyi +6779 -3312
  37. ansys/fluent/core/generated/solver/settings_builtin.py +515 -27
  38. ansys/fluent/core/generated/solver/settings_builtin.pyi +2 -18
  39. ansys/fluent/core/generated/solver/tui_261.py +4439 -3245
  40. ansys/fluent/core/launcher/container_launcher.py +19 -4
  41. ansys/fluent/core/launcher/fluent_container.py +51 -39
  42. ansys/fluent/core/launcher/launch_options.py +5 -4
  43. ansys/fluent/core/launcher/launcher.py +16 -3
  44. ansys/fluent/core/launcher/launcher_utils.py +63 -15
  45. ansys/fluent/core/launcher/pim_launcher.py +17 -3
  46. ansys/fluent/core/launcher/process_launch_string.py +3 -2
  47. ansys/fluent/core/launcher/server_info.py +7 -3
  48. ansys/fluent/core/launcher/slurm_launcher.py +4 -3
  49. ansys/fluent/core/launcher/standalone_launcher.py +6 -3
  50. ansys/fluent/core/launcher/watchdog.py +3 -3
  51. ansys/fluent/core/launcher/watchdog_exec +1 -1
  52. ansys/fluent/core/logger.py +3 -1
  53. ansys/fluent/core/module_config.py +363 -0
  54. ansys/fluent/core/pyfluent_warnings.py +2 -2
  55. ansys/fluent/core/report.py +0 -2
  56. ansys/fluent/core/search.py +43 -18
  57. ansys/fluent/core/services/api_upgrade.py +3 -2
  58. ansys/fluent/core/services/datamodel_se.py +4 -2
  59. ansys/fluent/core/services/health_check.py +3 -1
  60. ansys/fluent/core/services/interceptors.py +8 -6
  61. ansys/fluent/core/session.py +31 -3
  62. ansys/fluent/core/session_pure_meshing.py +1 -1
  63. ansys/fluent/core/session_shared.py +4 -4
  64. ansys/fluent/core/session_solver.py +13 -6
  65. ansys/fluent/core/session_utilities.py +7 -0
  66. ansys/fluent/core/solver/flobject.py +6 -4
  67. ansys/fluent/core/solver/flunits.py +2 -0
  68. ansys/fluent/core/solver/settings_builtin_bases.py +3 -3
  69. ansys/fluent/core/solver/settings_builtin_data.py +2 -14
  70. ansys/fluent/core/streaming_services/datamodel_event_streaming.py +3 -2
  71. ansys/fluent/core/streaming_services/datamodel_streaming.py +3 -1
  72. ansys/fluent/core/streaming_services/events_streaming.py +2 -18
  73. ansys/fluent/core/system_coupling.py +3 -1
  74. ansys/fluent/core/utils/__init__.py +0 -7
  75. ansys/fluent/core/utils/data_transfer.py +3 -3
  76. ansys/fluent/core/utils/file_transfer_service.py +24 -15
  77. ansys/fluent/core/utils/fluent_version.py +3 -3
  78. ansys/fluent/core/utils/networking.py +13 -4
  79. {ansys_fluent_core-0.34.2.dist-info → ansys_fluent_core-0.35.dev1.dist-info}/METADATA +8 -7
  80. {ansys_fluent_core-0.34.2.dist-info → ansys_fluent_core-0.35.dev1.dist-info}/RECORD +82 -81
  81. {ansys_fluent_core-0.34.2.dist-info → ansys_fluent_core-0.35.dev1.dist-info}/WHEEL +1 -1
  82. {ansys_fluent_core-0.34.2.dist-info → ansys_fluent_core-0.35.dev1.dist-info/licenses}/LICENSE +0 -0
@@ -56,7 +56,7 @@ from ansys.fluent.core.launcher.launch_options import (
56
56
  UIMode,
57
57
  _get_argvals_and_session,
58
58
  )
59
- from ansys.fluent.core.launcher.launcher_utils import is_compose
59
+ from ansys.fluent.core.launcher.launcher_utils import ComposeConfig
60
60
  from ansys.fluent.core.launcher.process_launch_string import (
61
61
  _build_fluent_launch_args_string,
62
62
  )
@@ -108,6 +108,8 @@ class DockerLauncher:
108
108
  gpu: bool | None = None,
109
109
  start_watchdog: bool | None = None,
110
110
  file_transfer_service: Any | None = None,
111
+ use_docker_compose: bool | None = None,
112
+ use_podman_compose: bool | None = None,
111
113
  ):
112
114
  """
113
115
  Launch a Fluent session in container mode.
@@ -161,6 +163,10 @@ class DockerLauncher:
161
163
  GUI-less Fluent sessions started by PyFluent are properly closed when the current Python process ends.
162
164
  file_transfer_service : Any, optional
163
165
  Service for uploading/downloading files to/from the server.
166
+ use_docker_compose: bool
167
+ Whether to use Docker Compose to launch Fluent.
168
+ use_podman_compose: bool
169
+ Whether to use Podman Compose to launch Fluent.
164
170
 
165
171
  Returns
166
172
  -------
@@ -198,12 +204,15 @@ class DockerLauncher:
198
204
  self._args = _build_fluent_launch_args_string(**self.argvals).split()
199
205
  if FluentMode.is_meshing(self.argvals["mode"]):
200
206
  self._args.append(" -meshing")
207
+ self._compose_config = ComposeConfig(use_docker_compose, use_podman_compose)
201
208
 
202
209
  def __call__(self):
203
210
 
204
211
  if self.argvals["dry_run"]:
205
212
  config_dict, *_ = configure_container_dict(
206
- self._args, **self.argvals["container_dict"]
213
+ self._args,
214
+ compose_config=self._compose_config,
215
+ **self.argvals["container_dict"],
207
216
  )
208
217
  dict_str = dict_to_str(config_dict)
209
218
  print("\nDocker container run configuration:\n")
@@ -214,11 +223,12 @@ class DockerLauncher:
214
223
  logger.debug(f"Fluent container launcher args: {self._args}")
215
224
  logger.debug(f"Fluent container launcher argvals:\n{dict_to_str(self.argvals)}")
216
225
 
217
- if is_compose():
226
+ if self._compose_config.is_compose:
218
227
  port, config_dict, container = start_fluent_container(
219
228
  self._args,
220
229
  self.argvals["container_dict"],
221
230
  self.argvals["start_timeout"],
231
+ compose_config=self._compose_config,
222
232
  )
223
233
 
224
234
  _, _, password = _get_server_info_from_container(config_dict=config_dict)
@@ -227,6 +237,7 @@ class DockerLauncher:
227
237
  self._args,
228
238
  self.argvals["container_dict"],
229
239
  self.argvals["start_timeout"],
240
+ compose_config=self._compose_config,
230
241
  )
231
242
 
232
243
  fluent_connection = FluentConnection(
@@ -237,18 +248,22 @@ class DockerLauncher:
237
248
  slurm_job_id=self.argvals and self.argvals.get("slurm_job_id"),
238
249
  inside_container=True,
239
250
  container=container,
251
+ compose_config=self._compose_config,
240
252
  )
241
253
 
254
+ self.argvals["compose_config"] = self._compose_config
255
+
242
256
  session = self.new_session(
243
257
  fluent_connection=fluent_connection,
244
258
  scheme_eval=fluent_connection._connection_interface.scheme_eval,
245
259
  file_transfer_service=self.file_transfer_service,
246
260
  start_transcript=self.argvals["start_transcript"],
261
+ launcher_args=self.argvals,
247
262
  )
248
263
 
249
264
  session._container = container
250
265
 
251
- if not is_compose():
266
+ if not self._compose_config.is_compose:
252
267
  if (
253
268
  self.argvals["start_watchdog"] is None
254
269
  and self.argvals["cleanup_on_exit"]
@@ -62,7 +62,7 @@ config_dict =
62
62
  'detach': True,
63
63
  'environment': {'ANSYSLMD_LICENSE_FILE': '2048@licenseserver.com',
64
64
  'REMOTING_PORTS': '54000/portspan=2'},
65
- 'fluent_image': 'ghcr.io/ansys/pyfluent:v23.2.0',
65
+ 'fluent_image': '<image registry>:v23.2.0',
66
66
  'labels': {'test_name': 'none'},
67
67
  'ports': {'54000': 54000},
68
68
  'volumes': ['/home/user/.local/share/ansys_fluent_core/examples:/mnt/pyfluent'],
@@ -85,7 +85,7 @@ from ansys.fluent.core.docker.utils import get_ghcr_fluent_image_name
85
85
  from ansys.fluent.core.launcher.error_handler import (
86
86
  LaunchFluentError,
87
87
  )
88
- from ansys.fluent.core.launcher.launcher_utils import is_compose
88
+ from ansys.fluent.core.launcher.launcher_utils import ComposeConfig
89
89
  from ansys.fluent.core.pyfluent_warnings import PyFluentDeprecationWarning
90
90
  from ansys.fluent.core.session import _parse_server_info_file
91
91
  from ansys.fluent.core.utils.deprecate import all_deprecators
@@ -131,7 +131,7 @@ def dict_to_str(dict: dict) -> str:
131
131
  This is useful for logging purposes, to avoid printing sensitive information such as license server details.
132
132
  """
133
133
 
134
- if "environment" in dict and os.getenv("PYFLUENT_HIDE_LOG_SECRETS") == "1":
134
+ if "environment" in dict and pyfluent.config.hide_log_secrets:
135
135
  modified_dict = dict.copy()
136
136
  modified_dict.pop("environment")
137
137
  return pformat(modified_dict)
@@ -170,6 +170,7 @@ def configure_container_dict(
170
170
  image_name: str | None = None,
171
171
  image_tag: str | None = None,
172
172
  file_transfer_service: Any | None = None,
173
+ compose_config: ComposeConfig | None = None,
173
174
  **container_dict,
174
175
  ) -> (dict, int, int, Path, bool):
175
176
  """Parses the parameters listed below, and sets up the container configuration file.
@@ -204,6 +205,8 @@ def configure_container_dict(
204
205
  Ignored if ``fluent_image`` has been specified.
205
206
  file_transfer_service : optional
206
207
  Supports file upload and download.
208
+ compose_config : ComposeConfig, optional
209
+ Configuration for Docker Compose, if using Docker Compose to launch the container.
207
210
  **container_dict
208
211
  Additional keyword arguments can be specified, they will be treated as Docker container run options
209
212
  to be passed directly to the Docker run execution. See examples below and `Docker run`_ documentation.
@@ -237,6 +240,8 @@ def configure_container_dict(
237
240
  See also :func:`start_fluent_container`.
238
241
  """
239
242
 
243
+ compose_config = compose_config if compose_config else ComposeConfig()
244
+
240
245
  if timeout is not None:
241
246
  warnings.warn(
242
247
  "configure_container_dict(timeout) is deprecated, use launch_fluent(start_timeout) instead.",
@@ -248,19 +253,15 @@ def configure_container_dict(
248
253
  # Starting with 'mount_source' because it is not tied to the 'working_dir'.
249
254
  # The intended 'mount_source' logic is as follows, if it is not directly specified:
250
255
  # 1. If 'file_transfer_service' is provided, use its 'mount_source'.
251
- # 2. Try to use the environment variable 'PYFLUENT_CONTAINER_MOUNT_SOURCE', if it is set.
252
- # 3. Use the value from 'pyfluent.CONTAINER_MOUNT_SOURCE', if it is set.
253
- # 4. If 'volumes' is specified in 'container_dict', try to infer the value from it.
254
- # 5. Finally, use the current working directory, which is always available.
256
+ # 2. Use the value from 'pyfluent.config.container_mount_source', if it is set.
257
+ # 3. If 'volumes' is specified in 'container_dict', try to infer the value from it.
258
+ # 4. Finally, use the current working directory, which is always available.
255
259
 
256
260
  if not mount_source:
257
261
  if file_transfer_service:
258
262
  mount_source = file_transfer_service.mount_source
259
263
  else:
260
- mount_source = os.getenv(
261
- "PYFLUENT_CONTAINER_MOUNT_SOURCE",
262
- pyfluent.CONTAINER_MOUNT_SOURCE,
263
- )
264
+ mount_source = pyfluent.config.container_mount_source
264
265
 
265
266
  if "volumes" in container_dict:
266
267
  if len(container_dict["volumes"]) != 1:
@@ -286,15 +287,14 @@ def configure_container_dict(
286
287
 
287
288
  # The intended 'mount_target' logic is as follows, if it is not directly specified:
288
289
  # 1. If 'working_dir' is specified in 'container_dict', use it as 'mount_target'.
289
- # 2. Use the environment variable 'PYFLUENT_CONTAINER_MOUNT_TARGET', if it is set.
290
- # 3. Try to infer the value from the 'volumes' keyword in 'container_dict', if available.
291
- # 4. Finally, use the value from 'pyfluent.CONTAINER_MOUNT_TARGET', which is always set.
290
+ # 2. Try to infer the value from the 'volumes' keyword in 'container_dict', if available.
291
+ # 3. Finally, use the value from 'pyfluent.config.container_mount_target', which is always set.
292
292
 
293
293
  if not mount_target:
294
294
  if "working_dir" in container_dict:
295
295
  mount_target = container_dict["working_dir"]
296
296
  else:
297
- mount_target = os.getenv("PYFLUENT_CONTAINER_MOUNT_TARGET")
297
+ mount_target = pyfluent.config.container_mount_target
298
298
 
299
299
  if "working_dir" in container_dict and mount_target:
300
300
  # working_dir will be set later to the final value of mount_target
@@ -305,7 +305,7 @@ def configure_container_dict(
305
305
 
306
306
  if not mount_target:
307
307
  logger.debug("No container 'mount_target' specified, using default value.")
308
- mount_target = pyfluent.CONTAINER_MOUNT_TARGET
308
+ mount_target = pyfluent.config.container_mount_target
309
309
 
310
310
  if "volumes" not in container_dict:
311
311
  container_dict.update(volumes=[f"{mount_source}:{mount_target}"])
@@ -326,8 +326,8 @@ def configure_container_dict(
326
326
  if not port_mapping and "ports" in container_dict:
327
327
  # take the specified 'port', OR the first port value from the specified 'ports', for Fluent to use
328
328
  port_mapping = container_dict["ports"]
329
- if not port_mapping and pyfluent.LAUNCH_FLUENT_PORT:
330
- port = pyfluent.LAUNCH_FLUENT_PORT
329
+ if not port_mapping and pyfluent.config.launch_fluent_port:
330
+ port = pyfluent.config.launch_fluent_port
331
331
  port_mapping = {port: port}
332
332
  if not port_mapping:
333
333
  port = get_free_port()
@@ -353,9 +353,11 @@ def configure_container_dict(
353
353
  "FLUENT_ALLOW_REMOTE_GRPC_CONNECTION": "1",
354
354
  }
355
355
  )
356
+ if compose_config.is_compose:
357
+ container_dict["environment"]["FLUENT_SERVER_INFO_PERMISSION_SYSTEM"] = "1"
356
358
 
357
359
  if "labels" not in container_dict:
358
- test_name = os.getenv("PYFLUENT_TEST_NAME", "none")
360
+ test_name = pyfluent.config.test_name
359
361
  container_dict.update(
360
362
  labels={"test_name": test_name},
361
363
  )
@@ -400,15 +402,14 @@ def configure_container_dict(
400
402
 
401
403
  if not fluent_image:
402
404
  if not image_tag:
403
- image_tag = os.getenv(
404
- "FLUENT_IMAGE_TAG", f"v{pyfluent.FLUENT_RELEASE_VERSION}"
405
- )
405
+ image_tag = pyfluent.config.fluent_image_tag
406
406
  if not image_name and image_tag:
407
- image_name = os.getenv(
408
- "FLUENT_IMAGE_NAME", get_ghcr_fluent_image_name(image_tag)
407
+ image_name = (
408
+ pyfluent.config.fluent_image_name
409
+ or get_ghcr_fluent_image_name(image_tag)
409
410
  )
410
411
  if not image_tag or not image_name:
411
- fluent_image = os.getenv("FLUENT_CONTAINER_IMAGE", None)
412
+ fluent_image = pyfluent.config.fluent_container_name
412
413
  elif image_tag and image_name:
413
414
  if image_tag.startswith("sha"):
414
415
  fluent_image = f"{image_name}@{image_tag}"
@@ -419,24 +420,19 @@ def configure_container_dict(
419
420
 
420
421
  container_dict["fluent_image"] = fluent_image
421
422
 
422
- if not pyfluent.FLUENT_AUTOMATIC_TRANSCRIPT:
423
+ if not pyfluent.config.fluent_automatic_transcript:
423
424
  if "environment" not in container_dict:
424
425
  container_dict["environment"] = {}
425
426
  container_dict["environment"]["FLUENT_NO_AUTOMATIC_TRANSCRIPT"] = "1"
426
427
 
427
- if os.getenv("REMOTING_NEW_DM_API") == "1":
428
- if "environment" not in container_dict:
429
- container_dict["environment"] = {}
430
- container_dict["environment"]["REMOTING_NEW_DM_API"] = "1"
431
-
432
- if pyfluent.LAUNCH_FLUENT_IP or os.getenv("REMOTING_SERVER_ADDRESS"):
428
+ if pyfluent.config.launch_fluent_ip or pyfluent.config.remoting_server_address:
433
429
  if "environment" not in container_dict:
434
430
  container_dict["environment"] = {}
435
431
  container_dict["environment"]["REMOTING_SERVER_ADDRESS"] = (
436
- pyfluent.LAUNCH_FLUENT_IP or os.getenv("REMOTING_SERVER_ADDRESS")
432
+ pyfluent.config.launch_fluent_ip or pyfluent.config.remoting_server_address
437
433
  )
438
434
 
439
- if pyfluent.LAUNCH_FLUENT_SKIP_PASSWORD_CHECK:
435
+ if pyfluent.config.launch_fluent_skip_password_check:
440
436
  if "environment" not in container_dict:
441
437
  container_dict["environment"] = {}
442
438
  container_dict["environment"]["FLUENT_LAUNCHED_FROM_PYFLUENT"] = "1"
@@ -451,9 +447,11 @@ def configure_container_dict(
451
447
  if k not in container_dict:
452
448
  container_dict[k] = v
453
449
 
450
+ if not Path(mount_source).exists():
451
+ Path(mount_source).mkdir(parents=True, exist_ok=True)
454
452
  host_server_info_file = Path(mount_source) / container_server_info_file.name
455
453
 
456
- if is_compose():
454
+ if compose_config.is_compose:
457
455
  container_dict["host_server_info_file"] = host_server_info_file
458
456
  container_dict["mount_source"] = mount_source
459
457
  container_dict["mount_target"] = mount_target
@@ -475,7 +473,10 @@ def configure_container_dict(
475
473
 
476
474
 
477
475
  def start_fluent_container(
478
- args: List[str], container_dict: dict | None = None, start_timeout: int = 60
476
+ args: List[str],
477
+ container_dict: dict | None = None,
478
+ start_timeout: int = 60,
479
+ compose_config: ComposeConfig | None = None,
479
480
  ) -> tuple[int, str, Any]:
480
481
  """Start a Fluent container.
481
482
 
@@ -488,6 +489,8 @@ def start_fluent_container(
488
489
  start_timeout : int, optional
489
490
  Timeout in seconds for the container to start. If not specified, it defaults to 60
490
491
  seconds.
492
+ compose_config : ComposeConfig, optional
493
+ Configuration for Docker Compose, if using Docker Compose to launch the container.
491
494
 
492
495
  Returns
493
496
  -------
@@ -509,10 +512,16 @@ def start_fluent_container(
509
512
  :func:`~ansys.fluent.core.launcher.launcher.launch_fluent()`.
510
513
  """
511
514
 
515
+ compose_config = compose_config if compose_config else ComposeConfig()
516
+
512
517
  if container_dict is None:
513
518
  container_dict = {}
514
519
 
515
- container_vars = configure_container_dict(args, **container_dict)
520
+ container_vars = configure_container_dict(
521
+ args,
522
+ compose_config=compose_config,
523
+ **container_dict,
524
+ )
516
525
 
517
526
  (
518
527
  config_dict,
@@ -531,10 +540,13 @@ def start_fluent_container(
531
540
  del timeout
532
541
 
533
542
  try:
534
- if is_compose():
543
+ if compose_config.is_compose:
535
544
  config_dict["fluent_port"] = port
536
545
 
537
- compose_container = ComposeBasedLauncher(container_dict=config_dict)
546
+ compose_container = ComposeBasedLauncher(
547
+ compose_config=compose_config,
548
+ container_dict=config_dict,
549
+ )
538
550
 
539
551
  if not compose_container.check_image_exists():
540
552
  logger.debug(
@@ -23,7 +23,6 @@
23
23
  """Provides a module for enums used in the PyFluent."""
24
24
 
25
25
  from enum import Enum
26
- import os
27
26
  import warnings
28
27
 
29
28
  from ansys.fluent.core.exceptions import DisallowedValuesError
@@ -267,11 +266,12 @@ def _get_fluent_launch_mode(start_container, container_dict, scheduler_options):
267
266
  fluent_launch_mode: LaunchMode
268
267
  Fluent launch mode.
269
268
  """
269
+ from ansys.fluent.core import config
270
+
270
271
  if pypim.is_configured():
271
272
  fluent_launch_mode = LaunchMode.PIM
272
273
  elif start_container is True or (
273
- start_container is None
274
- and (container_dict or os.getenv("PYFLUENT_LAUNCH_CONTAINER") == "1")
274
+ start_container is None and (container_dict or config.launch_fluent_container)
275
275
  ):
276
276
  fluent_launch_mode = LaunchMode.CONTAINER
277
277
  # Currently, only Slurm scheduler is supported and within SlurmLauncher we check the value of the scheduler
@@ -344,6 +344,7 @@ def _get_standalone_launch_fluent_version(argvals) -> FluentVersion | None:
344
344
  FluentVersion, optional
345
345
  Fluent version or ``None``
346
346
  """
347
+ from ansys.fluent.core import config
347
348
 
348
349
  # Look for Fluent version in the following order:
349
350
  # 1. product_version parameter passed with launch_fluent
@@ -357,7 +358,7 @@ def _get_standalone_launch_fluent_version(argvals) -> FluentVersion | None:
357
358
 
358
359
  # (DEV) if "PYFLUENT_FLUENT_ROOT" environment variable is defined, we cannot
359
360
  # determine the Fluent version, so returning None.
360
- if os.getenv("PYFLUENT_FLUENT_ROOT"):
361
+ if config.fluent_root:
361
362
  return None
362
363
 
363
364
  # 2. the latest ANSYS version from AWP_ROOT environment variables
@@ -103,7 +103,7 @@ def _show_gui_to_ui_mode(old_arg_val, **kwds):
103
103
  return UIMode.NO_GUI
104
104
  elif container_dict:
105
105
  return UIMode.NO_GUI
106
- elif os.getenv("PYFLUENT_LAUNCH_CONTAINER") == "1":
106
+ elif pyfluent.config.launch_fluent_container:
107
107
  return UIMode.NO_GUI
108
108
  else:
109
109
  return UIMode.GUI
@@ -174,6 +174,8 @@ def launch_fluent(
174
174
  start_watchdog: bool | None = None,
175
175
  scheduler_options: dict | None = None,
176
176
  file_transfer_service: Any | None = None,
177
+ use_docker_compose: bool | None = None,
178
+ use_podman_compose: bool | None = None,
177
179
  ) -> Meshing | PureMeshing | Solver | SolverIcing | SlurmFuture | dict:
178
180
  """Launch Fluent locally in server mode or connect to a running Fluent server
179
181
  instance.
@@ -299,6 +301,10 @@ def launch_fluent(
299
301
  specified in a similar manner to Fluent's scheduler options.
300
302
  file_transfer_service : optional
301
303
  File transfer service. Uploads/downloads files to/from the server.
304
+ use_docker_compose: bool
305
+ Whether to use Docker Compose to launch Fluent.
306
+ use_podman_compose: bool
307
+ Whether to use Podman Compose to launch Fluent.
302
308
 
303
309
  Returns
304
310
  -------
@@ -312,6 +318,8 @@ def launch_fluent(
312
318
  ------
313
319
  UnexpectedKeywordArgument
314
320
  If an unexpected keyword argument is provided.
321
+ ValueError
322
+ If both ``use_docker_compose`` and ``use_podman_compose`` are set to ``True``.
315
323
 
316
324
  Notes
317
325
  -----
@@ -322,8 +330,13 @@ def launch_fluent(
322
330
  if env is None:
323
331
  env = {}
324
332
 
333
+ if use_docker_compose and use_podman_compose:
334
+ raise ValueError(
335
+ "Cannot use both 'use_docker_compose' and 'use_podman_compose' at the same time."
336
+ )
337
+
325
338
  if start_timeout is None:
326
- start_timeout = int(os.getenv("PYFLUENT_FLUENT_LAUNCH_TIMEOUT", "60"))
339
+ start_timeout = pyfluent.config.launch_fluent_timeout
327
340
 
328
341
  def _mode_to_launcher_type(fluent_launch_mode: LaunchMode):
329
342
  launcher_mode_type = {
@@ -349,7 +362,7 @@ def launch_fluent(
349
362
  )
350
363
  common_args = launch_fluent_args.intersection(launcher_type_args)
351
364
  launcher_argvals = {arg: val for arg, val in argvals.items() if arg in common_args}
352
- if pyfluent.START_WATCHDOG is False:
365
+ if pyfluent.config.start_watchdog is False:
353
366
  launcher_argvals["start_watchdog"] = False
354
367
  launcher = launcher_type(**launcher_argvals)
355
368
  return launcher()
@@ -30,19 +30,61 @@ import socket
30
30
  import subprocess
31
31
  import time
32
32
  from typing import Any, Dict
33
+ import warnings
33
34
 
34
35
  from ansys.fluent.core.exceptions import InvalidArgument
36
+ from ansys.fluent.core.pyfluent_warnings import PyFluentDeprecationWarning
35
37
  from ansys.fluent.core.utils.networking import find_remoting_ip
36
38
 
37
39
  logger = logging.getLogger("pyfluent.launcher")
38
40
 
39
41
 
40
- def is_compose() -> bool:
41
- """Check if the Fluent launch is through compose."""
42
- return (
43
- os.getenv("PYFLUENT_USE_DOCKER_COMPOSE") == "1"
44
- or os.getenv("PYFLUENT_USE_PODMAN_COMPOSE") == "1"
45
- )
42
+ class ComposeConfig:
43
+ """Configuration for Docker or Podman Compose usage in PyFluent."""
44
+
45
+ def __init__(
46
+ self,
47
+ use_docker_compose: bool | None = None,
48
+ use_podman_compose: bool | None = None,
49
+ ):
50
+ from ansys.fluent.core import config
51
+
52
+ self._env_docker = config.use_docker_compose
53
+ self._env_podman = config.use_podman_compose
54
+
55
+ self._use_docker = use_docker_compose
56
+ self._use_podman = use_podman_compose
57
+
58
+ if use_docker_compose is None and self._env_docker:
59
+ self._warn_env_deprecated()
60
+ if use_podman_compose is None and self._env_podman:
61
+ self._warn_env_deprecated()
62
+
63
+ def _warn_env_deprecated(self):
64
+ warnings.warn(
65
+ (
66
+ "The environment variables 'PYFLUENT_USE_DOCKER_COMPOSE' and "
67
+ "'PYFLUENT_USE_PODMAN_COMPOSE' are deprecated. "
68
+ "Use the 'use_docker_compose' and 'use_podman_compose' parameters instead."
69
+ ),
70
+ category=PyFluentDeprecationWarning,
71
+ stacklevel=3,
72
+ )
73
+
74
+ @property
75
+ def use_docker_compose(self) -> bool:
76
+ """Check if Docker Compose is configured to be used."""
77
+ return self._use_docker if self._use_docker is not None else self._env_docker
78
+
79
+ @property
80
+ def use_podman_compose(self) -> bool:
81
+ """Check if Podman Compose is configured to be used."""
82
+ return self._use_podman if self._use_podman is not None else self._env_podman
83
+
84
+ @property
85
+ def is_compose(self) -> bool:
86
+ """Check if either Docker Compose or Podman Compose is configured to be used."""
87
+ return self.use_docker_compose or self.use_podman_compose
46
88
 
47
89
 
48
90
  def is_windows():
@@ -60,7 +102,8 @@ def _get_subprocess_kwargs_for_fluent(env: Dict[str, Any], argvals) -> Dict[str,
60
102
  kwargs.update(stdout=subprocess.PIPE)
61
103
  else:
62
104
  kwargs.update(
63
- stdout=pyfluent.LAUNCH_FLUENT_STDOUT, stderr=pyfluent.LAUNCH_FLUENT_STDERR
105
+ stdout=pyfluent.config.launch_fluent_stdout,
106
+ stderr=pyfluent.config.launch_fluent_stderr,
64
107
  )
65
108
  if is_windows():
66
109
  kwargs.update(shell=True, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
@@ -70,26 +113,31 @@ def _get_subprocess_kwargs_for_fluent(env: Dict[str, Any], argvals) -> Dict[str,
70
113
  fluent_env.update({k: str(v) for k, v in env.items()})
71
114
  fluent_env["REMOTING_THROW_LAST_TUI_ERROR"] = "1"
72
115
  fluent_env["REMOTING_THROW_LAST_SETTINGS_ERROR"] = "1"
73
- if pyfluent.CLEAR_FLUENT_PARA_ENVS:
116
+ if pyfluent.config.clear_fluent_para_envs:
74
117
  fluent_env.pop("PARA_NPROCS", None)
75
118
  fluent_env.pop("PARA_MESH_NPROCS", None)
76
119
 
77
- if pyfluent.LAUNCH_FLUENT_IP:
78
- fluent_env["REMOTING_SERVER_ADDRESS"] = pyfluent.LAUNCH_FLUENT_IP
120
+ if pyfluent.config.launch_fluent_ip:
121
+ fluent_env["REMOTING_SERVER_ADDRESS"] = pyfluent.config.launch_fluent_ip
79
122
 
80
- if pyfluent.LAUNCH_FLUENT_PORT:
81
- fluent_env["REMOTING_PORTS"] = f"{pyfluent.LAUNCH_FLUENT_PORT}/portspan=2"
123
+ if pyfluent.config.launch_fluent_port:
124
+ fluent_env["REMOTING_PORTS"] = (
125
+ f"{pyfluent.config.launch_fluent_port}/portspan=2"
126
+ )
82
127
 
83
- if pyfluent.LAUNCH_FLUENT_SKIP_PASSWORD_CHECK:
128
+ if pyfluent.config.launch_fluent_skip_password_check:
84
129
  fluent_env["FLUENT_LAUNCHED_FROM_PYFLUENT"] = "1"
85
130
 
86
131
  if not is_slurm:
87
- if pyfluent.INFER_REMOTING_IP and "REMOTING_SERVER_ADDRESS" not in fluent_env:
132
+ if (
133
+ pyfluent.config.infer_remoting_ip
134
+ and "REMOTING_SERVER_ADDRESS" not in fluent_env
135
+ ):
88
136
  remoting_ip = find_remoting_ip()
89
137
  if remoting_ip:
90
138
  fluent_env["REMOTING_SERVER_ADDRESS"] = remoting_ip
91
139
 
92
- if not pyfluent.FLUENT_AUTOMATIC_TRANSCRIPT:
140
+ if not pyfluent.config.fluent_automatic_transcript:
93
141
  fluent_env["FLUENT_NO_AUTOMATIC_TRANSCRIPT"] = "1"
94
142
 
95
143
  kwargs.update(env=fluent_env)
@@ -40,13 +40,14 @@ import logging
40
40
  import os
41
41
  from typing import Any, Dict
42
42
 
43
- from ansys.fluent.core.fluent_connection import FluentConnection
43
+ from ansys.fluent.core.fluent_connection import FluentConnection, _get_max_c_int_limit
44
44
  from ansys.fluent.core.launcher.launch_options import (
45
45
  Dimension,
46
46
  FluentLinuxGraphicsDriver,
47
47
  FluentMode,
48
48
  FluentWindowsGraphicsDriver,
49
49
  Precision,
50
+ UIMode,
50
51
  _get_argvals_and_session,
51
52
  )
52
53
  from ansys.fluent.core.session_meshing import Meshing
@@ -68,6 +69,7 @@ class PIMLauncher:
68
69
  def __init__(
69
70
  self,
70
71
  mode: FluentMode | str | None = None,
72
+ ui_mode: UIMode | str | None = None,
71
73
  graphics_driver: (
72
74
  FluentWindowsGraphicsDriver | FluentLinuxGraphicsDriver | str | None
73
75
  ) = None,
@@ -78,6 +80,7 @@ class PIMLauncher:
78
80
  start_timeout: int = 60,
79
81
  additional_arguments: str = "",
80
82
  cleanup_on_exit: bool = True,
83
+ dry_run: bool | None = None,
81
84
  start_transcript: bool = True,
82
85
  gpu: bool | None = None,
83
86
  start_watchdog: bool | None = None,
@@ -90,6 +93,8 @@ class PIMLauncher:
90
93
  ----------
91
94
  mode : FluentMode
92
95
  Specifies the launch mode of Fluent for targeting a specific session type.
96
+ ui_mode : UIMode
97
+ Defines the user interface mode for Fluent. Options correspond to values in the ``UIMode`` enum.
93
98
  graphics_driver : FluentWindowsGraphicsDriver or FluentLinuxGraphicsDriver
94
99
  Specifies the graphics driver for Fluent. Options are from the ``FluentWindowsGraphicsDriver`` enum
95
100
  (for Windows) or the ``FluentLinuxGraphicsDriver`` enum (for Linux).
@@ -115,6 +120,8 @@ class PIMLauncher:
115
120
  cleanup_on_exit : bool
116
121
  Determines whether to shut down the connected Fluent session upon exit or when calling
117
122
  the session's `exit()` method. Defaults to True.
123
+ dry_run : bool, optional
124
+ If True, returns a configuration dictionary instead of starting a Fluent session.
118
125
  start_transcript : bool
119
126
  Indicates whether to start streaming the Fluent transcript in the client. Defaults to True;
120
127
  streaming can be controlled via `transcript.start()` and `transcript.stop()` methods on the session object.
@@ -170,7 +177,9 @@ class PIMLauncher:
170
177
  FluentVersion(self.argvals["product_version"]).number
171
178
  )
172
179
  else:
173
- fluent_product_version = None
180
+ fluent_product_version = str(
181
+ FluentVersion(FluentVersion.current_release()).number
182
+ )
174
183
 
175
184
  return launch_remote_fluent(
176
185
  session_cls=self.new_session,
@@ -236,7 +245,12 @@ def launch_remote_fluent(
236
245
 
237
246
  instance.wait_for_ready()
238
247
 
239
- channel = instance.build_grpc_channel()
248
+ channel = instance.build_grpc_channel(
249
+ options=[
250
+ ("grpc.max_send_message_length", _get_max_c_int_limit()),
251
+ ("grpc.max_receive_message_length", _get_max_c_int_limit()),
252
+ ],
253
+ )
240
254
 
241
255
  fluent_connection = create_fluent_connection(
242
256
  channel=channel,
@@ -132,7 +132,7 @@ def _generate_launch_string(
132
132
  if " " in server_info_file_name:
133
133
  server_info_file_name = '"' + server_info_file_name + '"'
134
134
  launch_string += f" -sifile={server_info_file_name}"
135
- if not pyfluent.FLUENT_SHOW_MESH_AFTER_CASE_READ:
135
+ if not pyfluent.config.fluent_show_mesh_after_case_read:
136
136
  launch_string += " -nm"
137
137
  return launch_string
138
138
 
@@ -149,6 +149,7 @@ def get_fluent_exe_path(**launch_argvals) -> Path:
149
149
  Path
150
150
  Fluent executable path
151
151
  """
152
+ from ansys.fluent.core import config
152
153
 
153
154
  def get_exe_path(fluent_root: Path) -> Path:
154
155
  if launcher_utils.is_windows():
@@ -170,7 +171,7 @@ def get_fluent_exe_path(**launch_argvals) -> Path:
170
171
  return FluentVersion(product_version).get_fluent_exe_path()
171
172
 
172
173
  # (DEV) "PYFLUENT_FLUENT_ROOT" environment variable
173
- fluent_root = os.getenv("PYFLUENT_FLUENT_ROOT")
174
+ fluent_root = config.fluent_root
174
175
  if fluent_root:
175
176
  return get_exe_path(Path(fluent_root))
176
177