ansys-fluent-core 0.34.1__py3-none-any.whl → 0.35.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 (81) 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 +50 -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 +1 -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 +1 -1
  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 +55 -55
  15. ansys/fluent/core/generated/datamodel_231/meshing.py +209 -209
  16. ansys/fluent/core/generated/datamodel_232/flicing.py +45 -45
  17. ansys/fluent/core/generated/datamodel_232/meshing.py +205 -205
  18. ansys/fluent/core/generated/datamodel_241/flicing.py +30 -30
  19. ansys/fluent/core/generated/datamodel_241/meshing.py +298 -298
  20. ansys/fluent/core/generated/datamodel_242/flicing.py +35 -35
  21. ansys/fluent/core/generated/datamodel_242/meshing.py +321 -321
  22. ansys/fluent/core/generated/datamodel_242/part_management.py +3 -3
  23. ansys/fluent/core/generated/datamodel_251/flicing.py +40 -40
  24. ansys/fluent/core/generated/datamodel_251/meshing.py +315 -315
  25. ansys/fluent/core/generated/datamodel_251/part_management.py +6 -6
  26. ansys/fluent/core/generated/datamodel_252/flicing.py +45 -45
  27. ansys/fluent/core/generated/datamodel_252/meshing.py +398 -398
  28. ansys/fluent/core/generated/datamodel_261/flicing.py +50 -50
  29. ansys/fluent/core/generated/datamodel_261/meshing.py +406 -406
  30. ansys/fluent/core/generated/datamodel_261/meshing_utilities.py +616 -296
  31. ansys/fluent/core/generated/datamodel_261/part_management.py +10 -10
  32. ansys/fluent/core/generated/fluent_version_252.py +1 -1
  33. ansys/fluent/core/generated/fluent_version_261.py +3 -3
  34. ansys/fluent/core/generated/meshing/tui_261.py +1178 -1133
  35. ansys/fluent/core/generated/solver/settings_261.py +2378 -3023
  36. ansys/fluent/core/generated/solver/settings_261.pyi +1537 -1456
  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 +2606 -3483
  40. ansys/fluent/core/launcher/container_launcher.py +19 -4
  41. ansys/fluent/core/launcher/fluent_container.py +48 -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 -2
  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 +358 -0
  54. ansys/fluent/core/pyfluent_warnings.py +2 -2
  55. ansys/fluent/core/report.py +0 -2
  56. ansys/fluent/core/search.py +31 -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 +8 -2
  65. ansys/fluent/core/session_utilities.py +7 -0
  66. ansys/fluent/core/solver/flobject.py +6 -4
  67. ansys/fluent/core/solver/settings_builtin_bases.py +3 -3
  68. ansys/fluent/core/solver/settings_builtin_data.py +2 -14
  69. ansys/fluent/core/streaming_services/datamodel_event_streaming.py +3 -2
  70. ansys/fluent/core/streaming_services/datamodel_streaming.py +3 -1
  71. ansys/fluent/core/streaming_services/events_streaming.py +2 -18
  72. ansys/fluent/core/system_coupling.py +3 -1
  73. ansys/fluent/core/utils/__init__.py +0 -7
  74. ansys/fluent/core/utils/data_transfer.py +3 -3
  75. ansys/fluent/core/utils/file_transfer_service.py +24 -15
  76. ansys/fluent/core/utils/fluent_version.py +3 -3
  77. ansys/fluent/core/utils/networking.py +2 -2
  78. {ansys_fluent_core-0.34.1.dist-info → ansys_fluent_core-0.35.dev0.dist-info}/METADATA +1 -1
  79. {ansys_fluent_core-0.34.1.dist-info → ansys_fluent_core-0.35.dev0.dist-info}/RECORD +81 -80
  80. {ansys_fluent_core-0.34.1.dist-info → ansys_fluent_core-0.35.dev0.dist-info}/LICENSE +0 -0
  81. {ansys_fluent_core-0.34.1.dist-info → ansys_fluent_core-0.35.dev0.dist-info}/WHEEL +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()
@@ -350,11 +350,12 @@ def configure_container_dict(
350
350
  environment={
351
351
  "ANSYSLMD_LICENSE_FILE": license_server,
352
352
  "REMOTING_PORTS": f"{container_grpc_port}/portspan=2",
353
+ "FLUENT_ALLOW_REMOTE_GRPC_CONNECTION": "1",
353
354
  }
354
355
  )
355
356
 
356
357
  if "labels" not in container_dict:
357
- test_name = os.getenv("PYFLUENT_TEST_NAME", "none")
358
+ test_name = pyfluent.config.test_name
358
359
  container_dict.update(
359
360
  labels={"test_name": test_name},
360
361
  )
@@ -399,15 +400,14 @@ def configure_container_dict(
399
400
 
400
401
  if not fluent_image:
401
402
  if not image_tag:
402
- image_tag = os.getenv(
403
- "FLUENT_IMAGE_TAG", f"v{pyfluent.FLUENT_RELEASE_VERSION}"
404
- )
403
+ image_tag = pyfluent.config.fluent_image_tag
405
404
  if not image_name and image_tag:
406
- image_name = os.getenv(
407
- "FLUENT_IMAGE_NAME", get_ghcr_fluent_image_name(image_tag)
405
+ image_name = (
406
+ pyfluent.config.fluent_image_name
407
+ or get_ghcr_fluent_image_name(image_tag)
408
408
  )
409
409
  if not image_tag or not image_name:
410
- fluent_image = os.getenv("FLUENT_CONTAINER_IMAGE", None)
410
+ fluent_image = pyfluent.config.fluent_container_name
411
411
  elif image_tag and image_name:
412
412
  if image_tag.startswith("sha"):
413
413
  fluent_image = f"{image_name}@{image_tag}"
@@ -418,24 +418,19 @@ def configure_container_dict(
418
418
 
419
419
  container_dict["fluent_image"] = fluent_image
420
420
 
421
- if not pyfluent.FLUENT_AUTOMATIC_TRANSCRIPT:
421
+ if not pyfluent.config.fluent_automatic_transcript:
422
422
  if "environment" not in container_dict:
423
423
  container_dict["environment"] = {}
424
424
  container_dict["environment"]["FLUENT_NO_AUTOMATIC_TRANSCRIPT"] = "1"
425
425
 
426
- if os.getenv("REMOTING_NEW_DM_API") == "1":
427
- if "environment" not in container_dict:
428
- container_dict["environment"] = {}
429
- container_dict["environment"]["REMOTING_NEW_DM_API"] = "1"
430
-
431
- if pyfluent.LAUNCH_FLUENT_IP or os.getenv("REMOTING_SERVER_ADDRESS"):
426
+ if pyfluent.config.launch_fluent_ip or pyfluent.config.remoting_server_address:
432
427
  if "environment" not in container_dict:
433
428
  container_dict["environment"] = {}
434
429
  container_dict["environment"]["REMOTING_SERVER_ADDRESS"] = (
435
- pyfluent.LAUNCH_FLUENT_IP or os.getenv("REMOTING_SERVER_ADDRESS")
430
+ pyfluent.config.launch_fluent_ip or pyfluent.config.remoting_server_address
436
431
  )
437
432
 
438
- if pyfluent.LAUNCH_FLUENT_SKIP_PASSWORD_CHECK:
433
+ if pyfluent.config.launch_fluent_skip_password_check:
439
434
  if "environment" not in container_dict:
440
435
  container_dict["environment"] = {}
441
436
  container_dict["environment"]["FLUENT_LAUNCHED_FROM_PYFLUENT"] = "1"
@@ -452,7 +447,7 @@ def configure_container_dict(
452
447
 
453
448
  host_server_info_file = Path(mount_source) / container_server_info_file.name
454
449
 
455
- if is_compose():
450
+ if compose_config.is_compose:
456
451
  container_dict["host_server_info_file"] = host_server_info_file
457
452
  container_dict["mount_source"] = mount_source
458
453
  container_dict["mount_target"] = mount_target
@@ -474,7 +469,10 @@ def configure_container_dict(
474
469
 
475
470
 
476
471
  def start_fluent_container(
477
- args: List[str], container_dict: dict | None = None, start_timeout: int = 60
472
+ args: List[str],
473
+ container_dict: dict | None = None,
474
+ start_timeout: int = 60,
475
+ compose_config: ComposeConfig | None = None,
478
476
  ) -> tuple[int, str, Any]:
479
477
  """Start a Fluent container.
480
478
 
@@ -487,6 +485,8 @@ def start_fluent_container(
487
485
  start_timeout : int, optional
488
486
  Timeout in seconds for the container to start. If not specified, it defaults to 60
489
487
  seconds.
488
+ compose_config : ComposeConfig, optional
489
+ Configuration for Docker Compose, if using Docker Compose to launch the container.
490
490
 
491
491
  Returns
492
492
  -------
@@ -508,10 +508,16 @@ def start_fluent_container(
508
508
  :func:`~ansys.fluent.core.launcher.launcher.launch_fluent()`.
509
509
  """
510
510
 
511
+ compose_config = compose_config if compose_config else ComposeConfig()
512
+
511
513
  if container_dict is None:
512
514
  container_dict = {}
513
515
 
514
- container_vars = configure_container_dict(args, **container_dict)
516
+ container_vars = configure_container_dict(
517
+ args,
518
+ compose_config=compose_config,
519
+ **container_dict,
520
+ )
515
521
 
516
522
  (
517
523
  config_dict,
@@ -530,10 +536,13 @@ def start_fluent_container(
530
536
  del timeout
531
537
 
532
538
  try:
533
- if is_compose():
539
+ if compose_config.is_compose:
534
540
  config_dict["fluent_port"] = port
535
541
 
536
- compose_container = ComposeBasedLauncher(container_dict=config_dict)
542
+ compose_container = ComposeBasedLauncher(
543
+ compose_config=compose_config,
544
+ container_dict=config_dict,
545
+ )
537
546
 
538
547
  if not compose_container.check_image_exists():
539
548
  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