ansys-fluent-core 0.34.1__py3-none-any.whl → 0.35.0__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 (86) 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 +8 -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 +9 -12
  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 +45 -45
  15. ansys/fluent/core/generated/datamodel_231/meshing.py +183 -183
  16. ansys/fluent/core/generated/datamodel_232/flicing.py +25 -25
  17. ansys/fluent/core/generated/datamodel_232/meshing.py +173 -173
  18. ansys/fluent/core/generated/datamodel_241/flicing.py +30 -30
  19. ansys/fluent/core/generated/datamodel_241/meshing.py +246 -246
  20. ansys/fluent/core/generated/datamodel_242/flicing.py +25 -25
  21. ansys/fluent/core/generated/datamodel_242/meshing.py +273 -273
  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 +361 -361
  25. ansys/fluent/core/generated/datamodel_251/part_management.py +6 -6
  26. ansys/fluent/core/generated/datamodel_252/flicing.py +30 -30
  27. ansys/fluent/core/generated/datamodel_252/meshing.py +375 -375
  28. ansys/fluent/core/generated/datamodel_252/part_management.py +10 -10
  29. ansys/fluent/core/generated/datamodel_261/flicing.py +35 -35
  30. ansys/fluent/core/generated/datamodel_261/meshing.py +463 -407
  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_252.py +1 -1
  34. ansys/fluent/core/generated/fluent_version_261.py +3 -3
  35. ansys/fluent/core/generated/meshing/tui_261.py +1198 -1133
  36. ansys/fluent/core/generated/solver/settings_261.py +7514 -2195
  37. ansys/fluent/core/generated/solver/settings_261.pyi +4800 -1015
  38. ansys/fluent/core/generated/solver/settings_builtin.py +515 -27
  39. ansys/fluent/core/generated/solver/settings_builtin.pyi +2 -18
  40. ansys/fluent/core/generated/solver/tui_261.py +2396 -2171
  41. ansys/fluent/core/launcher/container_launcher.py +19 -4
  42. ansys/fluent/core/launcher/fluent_container.py +52 -39
  43. ansys/fluent/core/launcher/launch_options.py +4 -3
  44. ansys/fluent/core/launcher/launcher.py +16 -3
  45. ansys/fluent/core/launcher/launcher_utils.py +63 -15
  46. ansys/fluent/core/launcher/pim_launcher.py +17 -3
  47. ansys/fluent/core/launcher/process_launch_string.py +1 -1
  48. ansys/fluent/core/launcher/server_info.py +7 -3
  49. ansys/fluent/core/launcher/slurm_launcher.py +4 -2
  50. ansys/fluent/core/launcher/standalone_launcher.py +6 -3
  51. ansys/fluent/core/launcher/watchdog.py +3 -3
  52. ansys/fluent/core/launcher/watchdog_exec +1 -1
  53. ansys/fluent/core/logger.py +3 -1
  54. ansys/fluent/core/module_config.py +358 -0
  55. ansys/fluent/core/pyfluent_warnings.py +2 -2
  56. ansys/fluent/core/report.py +1 -3
  57. ansys/fluent/core/search.py +43 -18
  58. ansys/fluent/core/services/__init__.py +2 -0
  59. ansys/fluent/core/services/api_upgrade.py +3 -2
  60. ansys/fluent/core/services/datamodel_se.py +4 -2
  61. ansys/fluent/core/services/field_data.py +24 -0
  62. ansys/fluent/core/services/health_check.py +3 -1
  63. ansys/fluent/core/services/interceptors.py +8 -6
  64. ansys/fluent/core/services/settings.py +1 -1
  65. ansys/fluent/core/session.py +32 -5
  66. ansys/fluent/core/session_pure_meshing.py +1 -1
  67. ansys/fluent/core/session_shared.py +4 -4
  68. ansys/fluent/core/session_solver.py +13 -6
  69. ansys/fluent/core/session_utilities.py +7 -0
  70. ansys/fluent/core/solver/flobject.py +10 -4
  71. ansys/fluent/core/solver/flunits.py +2 -0
  72. ansys/fluent/core/solver/settings_builtin_bases.py +3 -3
  73. ansys/fluent/core/solver/settings_builtin_data.py +2 -14
  74. ansys/fluent/core/streaming_services/datamodel_event_streaming.py +3 -2
  75. ansys/fluent/core/streaming_services/datamodel_streaming.py +3 -1
  76. ansys/fluent/core/streaming_services/events_streaming.py +2 -18
  77. ansys/fluent/core/system_coupling.py +3 -1
  78. ansys/fluent/core/utils/__init__.py +0 -7
  79. ansys/fluent/core/utils/data_transfer.py +3 -3
  80. ansys/fluent/core/utils/file_transfer_service.py +24 -15
  81. ansys/fluent/core/utils/fluent_version.py +3 -3
  82. ansys/fluent/core/utils/networking.py +13 -4
  83. {ansys_fluent_core-0.34.1.dist-info → ansys_fluent_core-0.35.0.dist-info}/METADATA +8 -7
  84. {ansys_fluent_core-0.34.1.dist-info → ansys_fluent_core-0.35.0.dist-info}/RECORD +86 -85
  85. {ansys_fluent_core-0.34.1.dist-info → ansys_fluent_core-0.35.0.dist-info}/WHEEL +1 -1
  86. {ansys_fluent_core-0.34.1.dist-info → ansys_fluent_core-0.35.0.dist-info/licenses}/LICENSE +0 -0
@@ -23,10 +23,14 @@
23
23
  """A package providing Fluent's Solver and Meshing capabilities in Python."""
24
24
 
25
25
  import os
26
- from pathlib import Path
27
26
  import pydoc
27
+ import warnings
28
28
 
29
29
  # isort: off
30
+
31
+ # config must be initialized before logging setup.
32
+ from ansys.fluent.core.module_config import config
33
+
30
34
  # Logging has to be imported before importing other PyFluent modules
31
35
  from ansys.fluent.core.logger import set_console_logging_level # noqa: F401
32
36
 
@@ -73,13 +77,13 @@ from ansys.fluent.core.session_utilities import ( # noqa: F401
73
77
  SolverIcing,
74
78
  )
75
79
  from ansys.fluent.core.streaming_services.events_streaming import * # noqa: F401, F403
76
- from ansys.fluent.core.utils import fldoc, get_examples_download_dir
80
+ from ansys.fluent.core.utils import fldoc
77
81
  from ansys.fluent.core.utils.fluent_version import FluentVersion # noqa: F401
78
82
  from ansys.fluent.core.utils.setup_for_fluent import setup_for_fluent # noqa: F401
79
83
 
80
- __version__ = "0.34.1"
84
+ __version__ = "0.35.0"
81
85
 
82
- _VERSION_INFO = "Build date: August 05, 2025 03:19 UTC ShaID: ffa3845"
86
+ _VERSION_INFO = "Build date: September 09, 2025 06:25 UTC ShaID: 1d655a9"
83
87
  """
84
88
  Global variable indicating the version info of the PyFluent package.
85
89
  Build timestamp and commit hash are added to this variable during packaging.
@@ -108,86 +112,46 @@ def version_info() -> str:
108
112
  return _VERSION_INFO if _VERSION_INFO is not None else __version__
109
113
 
110
114
 
111
- # Latest released Fluent version
112
- FLUENT_RELEASE_VERSION = "25.2.0"
113
-
114
- # Current dev Fluent version
115
- FLUENT_DEV_VERSION = "26.1.0"
116
-
117
- # Path to the example input/data files are downloaded
118
- EXAMPLES_PATH = str(get_examples_download_dir())
119
-
120
- # Host path which is mounted to the container
121
- CONTAINER_MOUNT_SOURCE = None
122
-
123
- # Path inside the container where the host path is mounted
124
- CONTAINER_MOUNT_TARGET = "/home/container/workdir"
125
-
126
- # Set this to False to stop automatically inferring and setting REMOTING_SERVER_ADDRESS
127
- INFER_REMOTING_IP = True
128
-
129
- # Time in second to wait for response for each ip while inferring remoting ip
130
- INFER_REMOTING_IP_TIMEOUT_PER_IP = 2
131
-
132
115
  pydoc.text.docother = fldoc.docother.__get__(pydoc.text, pydoc.TextDoc)
133
116
 
134
- # Whether to use datamodel state caching
135
- DATAMODEL_USE_STATE_CACHE = True
136
-
137
- # Whether to use datamodel attribute caching
138
- DATAMODEL_USE_ATTR_CACHE = True
139
-
140
- # Whether to stream and cache commands state
141
- DATAMODEL_USE_NOCOMMANDS_DIFF_STATE = True
142
-
143
- # Whether to return the state changes on mutating datamodel rpcs
144
- DATAMODEL_RETURN_STATE_CHANGES = True
145
-
146
- # Whether to use remote gRPC file transfer service
147
- USE_FILE_TRANSFER_SERVICE = False
148
-
149
- # Directory where API files are written out during codegen
150
- CODEGEN_OUTDIR = os.getenv(
151
- "PYFLUENT_CODEGEN_OUTDIR", (Path(__file__) / ".." / "generated").resolve()
152
- )
153
-
154
- # Whether to show mesh in Fluent after case read
155
- FLUENT_SHOW_MESH_AFTER_CASE_READ = False
156
-
157
- # Whether to write the automatic transcript in Fluent
158
- FLUENT_AUTOMATIC_TRANSCRIPT = os.getenv("PYFLUENT_FLUENT_AUTOMATIC_TRANSCRIPT") == "1"
159
-
160
- # Whether to interrupt Fluent solver from PyFluent
161
- SUPPORT_SOLVER_INTERRUPT = False
162
-
163
- # Whether to start watchdog
164
- START_WATCHDOG = None
165
-
166
- # Health check timeout in seconds
167
- CHECK_HEALTH_TIMEOUT = 60
168
-
169
- # Whether to skip health check
170
- CHECK_HEALTH = True
171
-
172
- # Whether to print search results
173
- PRINT_SEARCH_RESULTS = True
174
-
175
- # Whether to clear environment variables related to Fluent parallel mode
176
- CLEAR_FLUENT_PARA_ENVS = False
177
-
178
- # Set stdout of the launched Fluent process
179
- # Valid values are same as subprocess.Popen's stdout argument
180
- LAUNCH_FLUENT_STDOUT = None
181
-
182
- # Set stderr of the launched Fluent process
183
- # Valid values are same as subprocess.Popen's stderr argument
184
- LAUNCH_FLUENT_STDERR = None
185
-
186
- # Set the IP address of the Fluent server while launching Fluent
187
- LAUNCH_FLUENT_IP = None
188
-
189
- # Set the port of the Fluent server while launching Fluent
190
- LAUNCH_FLUENT_PORT = None
191
117
 
192
- # Skip password check during rpc execution when Fluent is launched from PyFluent
193
- LAUNCH_FLUENT_SKIP_PASSWORD_CHECK = False
118
+ _config_by_deprecated_name = {
119
+ "FLUENT_RELEASE_VERSION": "fluent_release_version",
120
+ "FLUENT_DEV_VERSION": "fluent_dev_version",
121
+ "EXAMPLES_PATH": "examples_path",
122
+ "CONTAINER_MOUNT_SOURCE": "container_mount_source",
123
+ "CONTAINER_MOUNT_TARGET": "container_mount_target",
124
+ "INFER_REMOTING_IP": "infer_remoting_ip",
125
+ "INFER_REMOTING_IP_TIMEOUT_PER_IP": "infer_remoting_ip_timeout_per_ip",
126
+ "DATAMODEL_USE_STATE_CACHE": "datamodel_use_state_cache",
127
+ "DATAMODEL_USE_ATTR_CACHE": "datamodel_use_attr_cache",
128
+ "DATAMODEL_USE_NOCOMMANDS_DIFF_STATE": "datamodel_use_nocommands_diff_state",
129
+ "DATAMODEL_RETURN_STATE_CHANGES": "datamodel_return_state_changes",
130
+ "USE_FILE_TRANSFER_SERVICE": "use_file_transfer_service",
131
+ "CODEGEN_OUTDIR": "codegen_outdir",
132
+ "FLUENT_SHOW_MESH_AFTER_CASE_READ": "fluent_show_mesh_after_case_read",
133
+ "FLUENT_AUTOMATIC_TRANSCRIPT": "fluent_automatic_transcript",
134
+ "SUPPORT_SOLVER_INTERRUPT": "support_solver_interrupt",
135
+ "START_WATCHDOG": "start_watchdog",
136
+ "CHECK_HEALTH_TIMEOUT": "check_health_timeout",
137
+ "CHECK_HEALTH": "check_health",
138
+ "PRINT_SEARCH_RESULTS": "print_search_results",
139
+ "CLEAR_FLUENT_PARA_ENVS": "clear_fluent_para_envs",
140
+ "LAUNCH_FLUENT_STDOUT": "launch_fluent_stdout",
141
+ "LAUNCH_FLUENT_STDERR": "launch_fluent_stderr",
142
+ "LAUNCH_FLUENT_IP": "launch_fluent_ip",
143
+ "LAUNCH_FLUENT_PORT": "launch_fluent_port",
144
+ "LAUNCH_FLUENT_SKIP_PASSWORD_CHECK": "launch_fluent_skip_password_check",
145
+ }
146
+
147
+
148
+ def __getattr__(name: str) -> str:
149
+ """Get the value of a deprecated configuration variable."""
150
+ if name in _config_by_deprecated_name:
151
+ config_name = _config_by_deprecated_name[name]
152
+ warnings.warn(
153
+ f"'{name}' is deprecated, use 'config.{config_name}' instead.",
154
+ category=PyFluentDeprecationWarning,
155
+ )
156
+ return getattr(config, config_name)
157
+ raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
@@ -23,10 +23,10 @@
23
23
  """Module to generate Fluent API classes."""
24
24
 
25
25
  import argparse
26
- import os
27
26
  from pathlib import Path
28
27
  import pickle
29
28
 
29
+ from ansys.fluent.core import config
30
30
  from ansys.fluent.core.codegen import ( # noqa: F401
31
31
  builtin_settingsgen,
32
32
  datamodelgen,
@@ -51,7 +51,7 @@ def generate(version: str, static_infos: dict, verbose: bool = False):
51
51
  Path(api_tree_file).parent.mkdir(parents=True, exist_ok=True)
52
52
  with open(api_tree_file, "wb") as f:
53
53
  pickle.dump(api_tree, f)
54
- if os.getenv("PYFLUENT_CODEGEN_SKIP_BUILTIN_SETTINGS") != "1":
54
+ if not config.codegen_skip_builtin_settings:
55
55
  builtin_settingsgen.generate(version)
56
56
 
57
57
 
@@ -22,25 +22,38 @@
22
22
 
23
23
  """Generate builtin setting classes."""
24
24
 
25
- from ansys.fluent.core import CODEGEN_OUTDIR, FluentVersion
26
- from ansys.fluent.core.solver.flobject import CreatableNamedObjectMixin, NamedObject
25
+ import re
26
+
27
+ from ansys.fluent.core import FluentVersion, config
28
+ from ansys.fluent.core.solver.flobject import (
29
+ CreatableNamedObjectMixin,
30
+ NamedObject,
31
+ _ChildNamedObjectAccessorMixin,
32
+ )
27
33
  from ansys.fluent.core.solver.settings_builtin_data import DATA
28
34
  from ansys.fluent.core.utils.fluent_version import all_versions
29
35
 
30
- _PY_FILE = CODEGEN_OUTDIR / "solver" / "settings_builtin.py"
31
- _PYI_FILE = CODEGEN_OUTDIR / "solver" / "settings_builtin.pyi"
36
+ _PY_FILE = config.codegen_outdir / "solver" / "settings_builtin.py"
37
+ _PYI_FILE = config.codegen_outdir / "solver" / "settings_builtin.pyi"
32
38
 
33
39
 
34
40
  def _get_settings_root(version: str):
35
- from ansys.fluent.core import CODEGEN_OUTDIR, utils
41
+ from ansys.fluent.core import config, utils
36
42
 
37
43
  settings = utils.load_module(
38
44
  f"settings_{version}",
39
- CODEGEN_OUTDIR / "solver" / f"settings_{version}.py",
45
+ config.codegen_outdir / "solver" / f"settings_{version}.py",
40
46
  )
41
47
  return settings.root
42
48
 
43
49
 
50
+ def _convert_camel_case_to_snake_case(name: str) -> str:
51
+ """Convert CamelCase to snake_case."""
52
+ # Replace uppercase letters with lowercase and prepend an underscore
53
+ name = re.sub(r"(?<!^)(?=[A-Z])", "_", name).lower()
54
+ return name
55
+
56
+
44
57
  def _get_named_objects_in_path(root, path, kind):
45
58
  named_objects = []
46
59
  cls = root
@@ -52,6 +65,8 @@ def _get_named_objects_in_path(root, path, kind):
52
65
  cls = cls.child_object_type
53
66
  final_type = ""
54
67
  if kind == "NamedObject":
68
+ if not issubclass(cls, (NamedObject, _ChildNamedObjectAccessorMixin)):
69
+ raise TypeError(f"{cls.__name__} is not NamedObject type.")
55
70
  if issubclass(cls, CreatableNamedObjectMixin):
56
71
  final_type = "Creatable"
57
72
  else:
@@ -62,7 +77,7 @@ def _get_named_objects_in_path(root, path, kind):
62
77
  def generate(version: str):
63
78
  """Generate builtin setting classes."""
64
79
  print("Generating builtin settings...")
65
- CODEGEN_OUTDIR.mkdir(exist_ok=True)
80
+ config.codegen_outdir.mkdir(exist_ok=True)
66
81
  root = _get_settings_root(version)
67
82
  version = FluentVersion(version)
68
83
  with open(_PY_FILE, "w") as f:
@@ -72,23 +87,52 @@ def generate(version: str):
72
87
  "from ansys.fluent.core.solver.flobject import SettingsBase\n\n\n"
73
88
  )
74
89
  f.write("__all__ = [\n")
75
- for name, _ in DATA.items():
90
+ for name, (kind, _) in DATA.items():
76
91
  f.write(f' "{name}",\n')
92
+ if kind == "Command":
93
+ command_name = _convert_camel_case_to_snake_case(name)
94
+ f.write(f' "{command_name}",\n')
77
95
  f.write("]\n\n")
78
96
  for name, v in DATA.items():
79
97
  kind, path = v
80
98
  if isinstance(path, dict):
99
+ version_supported = False
81
100
  for version_set, p in path.items():
82
101
  if version in version_set:
83
102
  path = p
103
+ version_supported = True
84
104
  break
105
+ if not version_supported:
106
+ continue
85
107
  named_objects, final_type = _get_named_objects_in_path(root, path, kind)
86
108
  if kind == "NamedObject":
87
109
  kind = f"{final_type}NamedObject"
88
110
  f.write(f"class {name}(_{kind}Setting):\n")
89
- doc_kind = "command" if kind == "Command" else "setting"
111
+ doc_kind = "command object" if kind == "Command" else "setting"
90
112
  f.write(f' """{name} {doc_kind}."""\n\n')
113
+ f.write(f' _db_name = "{name}"\n\n')
114
+ f.write(" def __init__(self")
115
+ for named_object in named_objects:
116
+ f.write(f", {named_object}: str")
117
+ f.write(", settings_source: SettingsBase | Solver | None = None")
118
+ if kind == "NonCreatableNamedObject":
119
+ f.write(", name: str = None")
120
+ elif kind == "CreatableNamedObject":
121
+ f.write(", name: str = None, new_instance_name: str = None")
122
+ f.write("):\n")
123
+ f.write(" super().__init__(settings_source=settings_source")
124
+ if kind == "NonCreatableNamedObject":
125
+ f.write(", name=name")
126
+ elif kind == "CreatableNamedObject":
127
+ f.write(", name=name, new_instance_name=new_instance_name")
128
+ for named_object in named_objects:
129
+ f.write(f", {named_object}={named_object}")
130
+ f.write(")\n\n")
91
131
  if kind == "Command":
132
+ command_name = _convert_camel_case_to_snake_case(name)
133
+ f.write(f"class {command_name}(_{kind}Setting):\n")
134
+ f.write(f' """{command_name} command."""\n\n')
135
+ f.write(f' _db_name = "{name}"\n\n')
92
136
  f.write(
93
137
  " def __new__(cls, settings_source: SettingsBase | Solver | None = None, **kwargs):\n"
94
138
  )
@@ -96,25 +140,7 @@ def generate(version: str):
96
140
  f.write(
97
141
  " instance.__init__(settings_source=settings_source, **kwargs)\n"
98
142
  )
99
- f.write(" return instance(**kwargs")
100
- else:
101
- f.write(" def __init__(self")
102
- for named_object in named_objects:
103
- f.write(f", {named_object}: str")
104
- f.write(", settings_source: SettingsBase | Solver | None = None")
105
- if kind == "NonCreatableNamedObject":
106
- f.write(", name: str = None")
107
- elif kind == "CreatableNamedObject":
108
- f.write(", name: str = None, new_instance_name: str = None")
109
- f.write("):\n")
110
- f.write(" super().__init__(settings_source=settings_source")
111
- if kind == "NonCreatableNamedObject":
112
- f.write(", name=name")
113
- elif kind == "CreatableNamedObject":
114
- f.write(", name=name, new_instance_name=new_instance_name")
115
- for named_object in named_objects:
116
- f.write(f", {named_object}={named_object}")
117
- f.write(")\n\n")
143
+ f.write(" return instance(**kwargs)\n\n")
118
144
 
119
145
  with open(_PYI_FILE, "w") as f:
120
146
  for version in FluentVersion:
@@ -210,7 +210,9 @@ class DataModelStaticInfo:
210
210
  self.static_info = None
211
211
  if rules_save_name == "":
212
212
  rules_save_name = rules
213
- datamodel_dir = (pyfluent.CODEGEN_OUTDIR / f"datamodel_{version}").resolve()
213
+ datamodel_dir = (
214
+ pyfluent.config.codegen_outdir / f"datamodel_{version}"
215
+ ).resolve()
214
216
  datamodel_dir.mkdir(exist_ok=True)
215
217
  self.file_name = (
216
218
  datamodel_dir / f"{datamodel_file_name_map[rules_save_name]}.py"
@@ -22,14 +22,14 @@
22
22
 
23
23
  """Module to write Fluent version information."""
24
24
 
25
- from ansys.fluent.core import CODEGEN_OUTDIR, FluentVersion, launch_fluent
25
+ from ansys.fluent.core import FluentVersion, config, launch_fluent
26
26
 
27
27
 
28
28
  def print_fluent_version(app_utilities):
29
29
  """Write Fluent version information to file."""
30
30
  version = FluentVersion(app_utilities.get_product_version()).number
31
31
  build_info = app_utilities.get_build_info()
32
- version_file = (CODEGEN_OUTDIR / f"fluent_version_{version}.py").resolve()
32
+ version_file = (config.codegen_outdir / f"fluent_version_{version}.py").resolve()
33
33
  with open(version_file, "w", encoding="utf8") as f:
34
34
  f.write(f'FLUENT_VERSION = "{version}"\n')
35
35
  f.write(f'FLUENT_BUILD_TIME = "{build_info.build_time}"\n')
@@ -153,6 +153,7 @@ def _populate_data(cls, api_tree: dict, version: str) -> dict:
153
153
  else:
154
154
  data["child_object_type"] = None
155
155
  data["allowed_values"] = getattr(cls, "_allowed_values", [])
156
+ data["has_migration_adapter"] = getattr(cls, "_has_migration_adapter", False)
156
157
  return data
157
158
 
158
159
 
@@ -316,6 +317,12 @@ def _write_data(cls_name: str, python_name: str, data: dict, f: IO, f_stub: IO |
316
317
  s_stub.write(
317
318
  f" {to_constant_name(allowed_value)}: Final[str] = {allowed_value!r}\n"
318
319
  )
320
+ if data["allowed_values"]:
321
+ s.write(f" _allowed_values = {data['allowed_values']!r}\n")
322
+ s_stub.write(" _allowed_values: list[str]\n")
323
+ if data["has_migration_adapter"]:
324
+ s.write(" _has_migration_adapter = True\n")
325
+ s_stub.write(" _has_migration_adapter: bool\n")
319
326
  s.write("\n")
320
327
  s_stub.write("\n")
321
328
  for name, (python_name, data, hash_, should_write_stub) in classes_to_write.items():
@@ -355,7 +362,7 @@ def generate(version: str, static_infos: dict, verbose: bool = False) -> None:
355
362
  shash = _gethash(sinfo)
356
363
  if not sinfo:
357
364
  return {"<solver_session>": api_tree}
358
- output_dir = (pyfluent.CODEGEN_OUTDIR / "solver").resolve()
365
+ output_dir = (pyfluent.config.codegen_outdir / "solver").resolve()
359
366
  output_dir.mkdir(parents=True, exist_ok=True)
360
367
  output_file = output_dir / f"settings_{version}.py"
361
368
  output_stub_file = output_dir / f"settings_{version}.pyi"
@@ -69,7 +69,7 @@ _ROOT_DIR = Path(__file__) / ".." / ".." / ".." / ".." / ".." / ".."
69
69
 
70
70
 
71
71
  def _get_tui_filepath(mode: str, version: str):
72
- return (pyfluent.CODEGEN_OUTDIR / mode / f"tui_{version}.py").resolve()
72
+ return (pyfluent.config.codegen_outdir / mode / f"tui_{version}.py").resolve()
73
73
 
74
74
 
75
75
  _INDENT_STEP = 4
@@ -96,8 +96,8 @@ _XML_HELPSTRINGS = {}
96
96
 
97
97
 
98
98
  def _copy_tui_help_xml_file(version: str):
99
- if os.getenv("PYFLUENT_LAUNCH_CONTAINER") == "1":
100
- image_tag = os.getenv("FLUENT_IMAGE_TAG", "v25.1.0")
99
+ if pyfluent.config.launch_fluent_container:
100
+ image_tag = pyfluent.config.fluent_image_tag
101
101
  image_name = f"{get_ghcr_fluent_image_name(image_tag)}:{image_tag}"
102
102
  container_name = uuid.uuid4().hex
103
103
  is_linux = platform.system() == "Linux"
@@ -347,7 +347,7 @@ def generate(version, static_infos: dict, verbose: bool = False):
347
347
  api_tree["<solver_session>"] = TUIGenerator(
348
348
  "solver", version, static_infos, verbose
349
349
  ).generate()
350
- if os.getenv("PYFLUENT_HIDE_LOG_SECRETS") != "1":
350
+ if not pyfluent.config.hide_log_secrets:
351
351
  logger.info(
352
352
  "XML help is available but not picked for the following %i paths: ",
353
353
  len(_XML_HELPSTRINGS),
@@ -126,7 +126,7 @@ class _CacheImpl:
126
126
 
127
127
  def _is_dict_parameter_type(version: FluentVersion, rules: str, rules_path: str):
128
128
  """Check if a parameter is a dict type."""
129
- from ansys.fluent.core import CODEGEN_OUTDIR
129
+ from ansys.fluent.core import config
130
130
  from ansys.fluent.core.services.datamodel_se import (
131
131
  PyDictionary,
132
132
  PyNamedObjectContainer,
@@ -136,7 +136,7 @@ def _is_dict_parameter_type(version: FluentVersion, rules: str, rules_path: str)
136
136
 
137
137
  try:
138
138
  module = load_module(
139
- rules, CODEGEN_OUTDIR / f"datamodel_{version.number}" / f"{rules}.py"
139
+ rules, config.codegen_outdir / f"datamodel_{version.number}" / f"{rules}.py"
140
140
  )
141
141
  except FileNotFoundError: # no codegen or during codegen
142
142
  return False
@@ -22,7 +22,6 @@
22
22
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
23
  # SOFTWARE.
24
24
 
25
- import os
26
25
  import subprocess
27
26
  import uuid
28
27
 
@@ -32,10 +31,13 @@ from .utils import get_ghcr_fluent_image_name
32
31
  class ComposeBasedLauncher:
33
32
  """Launch Fluent through docker or Podman compose."""
34
33
 
35
- def __init__(self, *, container_dict):
34
+ def __init__(self, compose_config, container_dict):
35
+ from ansys.fluent.core import config
36
+
37
+ self._compose_config = compose_config
36
38
  self._compose_name = f"pyfluent_compose_{uuid.uuid4().hex}"
37
39
  self._container_dict = container_dict
38
- image_tag = os.getenv("FLUENT_IMAGE_TAG")
40
+ image_tag = config.fluent_image_tag
39
41
  self._image_name = (
40
42
  container_dict.get("fluent_image")
41
43
  or f"{get_ghcr_fluent_image_name(image_tag)}:{image_tag}"
@@ -45,9 +47,6 @@ class ComposeBasedLauncher:
45
47
 
46
48
  self._compose_file = self._get_compose_file(container_dict)
47
49
 
48
- def _is_podman_selected(self):
49
- return os.getenv("PYFLUENT_USE_PODMAN_COMPOSE") == "1"
50
-
51
50
  def _get_compose_file(self, container_dict):
52
51
  """Generates compose file for the Docker Compose setup.
53
52
 
@@ -132,14 +131,14 @@ class ComposeBasedLauncher:
132
131
  """
133
132
 
134
133
  # Determine the compose command
135
- if os.getenv("PYFLUENT_USE_PODMAN_COMPOSE") == "1":
134
+ if self._compose_config.use_podman_compose:
136
135
  self._compose_cmds = (
137
136
  ["sudo", "podman", "compose"]
138
137
  if hasattr(self, "_container_source")
139
138
  and "sudo" in self._container_source
140
139
  else ["podman", "compose"]
141
140
  )
142
- elif os.getenv("PYFLUENT_USE_DOCKER_COMPOSE") == "1":
141
+ elif self._compose_config.use_docker_compose:
143
142
  self._compose_cmds = ["docker", "compose"]
144
143
  else:
145
144
  raise RuntimeError("Neither Docker nor Podman is specified.")
@@ -151,7 +150,7 @@ class ComposeBasedLauncher:
151
150
  try:
152
151
  cmd = self._container_source + ["images", "-q", self._image_name]
153
152
  # Podman users do not always configure rootless mode in /etc/subuids and /etc/subgids
154
- if self._is_podman_selected():
153
+ if self._compose_config.use_podman_compose:
155
154
  sudo_cmd = ["sudo"] + cmd
156
155
  output_1 = subprocess.check_output(cmd)
157
156
  output_2 = subprocess.check_output(sudo_cmd)
@@ -29,7 +29,7 @@ def get_ghcr_fluent_image_name(image_tag: str):
29
29
  """
30
30
  Get the Fluent image name from GitHub registry based on the image tag.
31
31
  """
32
- if image_tag >= "v26.1":
32
+ if image_tag.startswith("sha256:") or image_tag >= "v26.1":
33
33
  return "ghcr.io/ansys/fluent"
34
34
  else:
35
35
  return "ghcr.io/ansys/pyfluent"
@@ -49,16 +49,16 @@ def delete_downloads():
49
49
 
50
50
  Notes
51
51
  -----
52
- The default examples path is given by ``pyfluent.EXAMPLES_PATH``.
52
+ The default examples path is given by ``pyfluent.config.examples_path``.
53
53
  """
54
- shutil.rmtree(pyfluent.EXAMPLES_PATH)
55
- os.makedirs(pyfluent.EXAMPLES_PATH)
54
+ shutil.rmtree(pyfluent.config.examples_path)
55
+ os.makedirs(pyfluent.config.examples_path)
56
56
 
57
57
 
58
58
  def _decompress(file_name: str) -> None:
59
59
  """Decompress zipped file."""
60
60
  zip_ref = zipfile.ZipFile(file_name, "r")
61
- zip_ref.extractall(pyfluent.EXAMPLES_PATH)
61
+ zip_ref.extractall(pyfluent.config.examples_path)
62
62
  return zip_ref.close()
63
63
 
64
64
 
@@ -81,10 +81,7 @@ def _retrieve_file(
81
81
  """Download specified file from specified URL."""
82
82
  file_name = os.path.basename(file_name)
83
83
  if save_path is None:
84
- save_path = os.getenv(
85
- "PYFLUENT_CONTAINER_MOUNT_SOURCE",
86
- pyfluent.CONTAINER_MOUNT_SOURCE or os.getcwd(),
87
- )
84
+ save_path = pyfluent.config.container_mount_source or os.getcwd()
88
85
  else:
89
86
  save_path = os.path.abspath(save_path)
90
87
  local_path = os.path.join(save_path, file_name)
@@ -140,7 +137,7 @@ def download_file(
140
137
  save_path : str, optional
141
138
  Path to download the specified file to.
142
139
  return_without_path : bool, optional
143
- When unspecified, defaults to False, unless the PYFLUENT_LAUNCH_CONTAINER=1 environment variable is specified,
140
+ When unspecified, defaults to False, unless the launch_fluent_container config is set to True,
144
141
  in which case defaults to True.
145
142
  Relevant when using Fluent Docker container images, as the full path for the imported file from
146
143
  the host side is not necessarily going to be the same as the one for Fluent inside the container.
@@ -180,8 +177,8 @@ def download_file(
180
177
  'bracket.iges'
181
178
  """
182
179
  if return_without_path is None:
183
- if os.getenv("PYFLUENT_LAUNCH_CONTAINER") == "1":
184
- if pyfluent.USE_FILE_TRANSFER_SERVICE:
180
+ if pyfluent.config.launch_fluent_container:
181
+ if pyfluent.config.use_file_transfer_service:
185
182
  return_without_path = False
186
183
  else:
187
184
  return_without_path = True
@@ -212,7 +209,7 @@ def path(file_name: str):
212
209
  """
213
210
  if os.path.isabs(file_name):
214
211
  return file_name
215
- file_path = Path(pyfluent.EXAMPLES_PATH) / file_name
212
+ file_path = Path(pyfluent.config.examples_path) / file_name
216
213
  if file_path.is_file():
217
214
  return str(file_path)
218
215
  else: