ansys-fluent-core 0.34.dev0__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.
- ansys/fluent/core/__init__.py +48 -84
- ansys/fluent/core/codegen/allapigen.py +2 -2
- ansys/fluent/core/codegen/builtin_settingsgen.py +41 -13
- ansys/fluent/core/codegen/datamodelgen.py +3 -1
- ansys/fluent/core/codegen/print_fluent_version.py +2 -2
- ansys/fluent/core/codegen/settingsgen.py +18 -6
- ansys/fluent/core/codegen/tuigen.py +6 -5
- ansys/fluent/core/data_model_cache.py +2 -2
- ansys/fluent/core/docker/docker_compose.py +11 -9
- ansys/fluent/core/docker/utils.py +35 -0
- ansys/fluent/core/examples/downloads.py +8 -11
- ansys/fluent/core/exceptions.py +13 -1
- ansys/fluent/core/field_data_interfaces.py +239 -38
- ansys/fluent/core/file_session.py +167 -61
- ansys/fluent/core/fluent_connection.py +41 -26
- ansys/fluent/core/generated/api_tree/api_objects.json +1 -1
- ansys/fluent/core/generated/datamodel_231/flicing.py +40 -40
- ansys/fluent/core/generated/datamodel_231/meshing.py +231 -231
- ansys/fluent/core/generated/datamodel_232/flicing.py +50 -50
- ansys/fluent/core/generated/datamodel_232/meshing.py +189 -189
- ansys/fluent/core/generated/datamodel_241/flicing.py +30 -30
- ansys/fluent/core/generated/datamodel_241/meshing.py +290 -290
- ansys/fluent/core/generated/datamodel_242/flicing.py +50 -50
- ansys/fluent/core/generated/datamodel_242/meshing.py +331 -331
- ansys/fluent/core/generated/datamodel_242/part_management.py +6 -6
- ansys/fluent/core/generated/datamodel_251/flicing.py +65 -65
- ansys/fluent/core/generated/datamodel_251/meshing.py +300 -300
- ansys/fluent/core/generated/datamodel_251/part_management.py +6 -6
- ansys/fluent/core/generated/datamodel_252/flicing.py +25 -25
- ansys/fluent/core/generated/datamodel_252/meshing.py +382 -382
- ansys/fluent/core/generated/datamodel_252/part_management.py +10 -10
- ansys/fluent/core/generated/datamodel_261/flicing.py +45 -45
- ansys/fluent/core/generated/datamodel_261/meshing.py +454 -435
- ansys/fluent/core/generated/datamodel_261/part_management.py +5 -5
- ansys/fluent/core/generated/datamodel_261/preferences.py +7 -0
- ansys/fluent/core/generated/fluent_version_252.py +1 -1
- ansys/fluent/core/generated/fluent_version_261.py +3 -3
- ansys/fluent/core/generated/meshing/tui_261.py +54 -3
- ansys/fluent/core/generated/solver/settings_231.py +1 -0
- ansys/fluent/core/generated/solver/settings_231.pyi +3025 -1
- ansys/fluent/core/generated/solver/settings_232.py +1 -0
- ansys/fluent/core/generated/solver/settings_232.pyi +3425 -1
- ansys/fluent/core/generated/solver/settings_241.py +1 -0
- ansys/fluent/core/generated/solver/settings_241.pyi +4423 -1
- ansys/fluent/core/generated/solver/settings_242.py +1 -0
- ansys/fluent/core/generated/solver/settings_242.pyi +5474 -1
- ansys/fluent/core/generated/solver/settings_251.py +11 -0
- ansys/fluent/core/generated/solver/settings_251.pyi +6006 -1
- ansys/fluent/core/generated/solver/settings_252.py +11 -1
- ansys/fluent/core/generated/solver/settings_252.pyi +6782 -2
- ansys/fluent/core/generated/solver/settings_261.py +5592 -2740
- ansys/fluent/core/generated/solver/settings_261.pyi +10335 -1994
- ansys/fluent/core/generated/solver/settings_builtin.py +560 -38
- ansys/fluent/core/generated/solver/settings_builtin.pyi +24 -18
- ansys/fluent/core/generated/solver/tui_261.py +409 -285
- ansys/fluent/core/launcher/container_launcher.py +25 -6
- ansys/fluent/core/launcher/error_handler.py +1 -1
- ansys/fluent/core/launcher/fluent_container.py +97 -45
- ansys/fluent/core/launcher/launch_options.py +5 -4
- ansys/fluent/core/launcher/launcher.py +18 -2
- ansys/fluent/core/launcher/launcher_utils.py +63 -15
- ansys/fluent/core/launcher/pim_launcher.py +17 -3
- ansys/fluent/core/launcher/process_launch_string.py +3 -2
- ansys/fluent/core/launcher/server_info.py +7 -3
- ansys/fluent/core/launcher/slurm_launcher.py +4 -2
- ansys/fluent/core/launcher/standalone_launcher.py +6 -3
- ansys/fluent/core/launcher/watchdog.py +6 -6
- ansys/fluent/core/launcher/watchdog_exec +1 -1
- ansys/fluent/core/logger.py +3 -1
- ansys/fluent/core/module_config.py +358 -0
- ansys/fluent/core/pyfluent_warnings.py +9 -3
- ansys/fluent/core/report.py +2 -2
- ansys/fluent/core/search.py +34 -13
- ansys/fluent/core/services/__init__.py +2 -2
- ansys/fluent/core/services/api_upgrade.py +3 -2
- ansys/fluent/core/services/app_utilities.py +39 -0
- ansys/fluent/core/services/datamodel_se.py +4 -2
- ansys/fluent/core/services/deprecated_field_data.py +4 -4
- ansys/fluent/core/services/field_data.py +185 -49
- ansys/fluent/core/services/health_check.py +3 -1
- ansys/fluent/core/services/interceptors.py +8 -6
- ansys/fluent/core/services/reduction.py +16 -5
- ansys/fluent/core/services/settings.py +1 -0
- ansys/fluent/core/session.py +47 -4
- ansys/fluent/core/session_pure_meshing.py +6 -6
- ansys/fluent/core/session_pure_meshing.pyi +1 -0
- ansys/fluent/core/session_shared.py +4 -4
- ansys/fluent/core/session_solver.py +41 -10
- ansys/fluent/core/session_solver.pyi +1 -0
- ansys/fluent/core/session_utilities.py +7 -0
- ansys/fluent/core/solver/error_message.py +2 -2
- ansys/fluent/core/solver/flobject.py +192 -123
- ansys/fluent/core/solver/function/reduction.py +37 -9
- ansys/fluent/core/solver/settings_builtin_bases.py +3 -3
- ansys/fluent/core/solver/settings_builtin_data.py +7 -17
- ansys/fluent/core/streaming_services/datamodel_event_streaming.py +3 -2
- ansys/fluent/core/streaming_services/datamodel_streaming.py +3 -1
- ansys/fluent/core/streaming_services/events_streaming.py +2 -18
- ansys/fluent/core/system_coupling.py +3 -1
- ansys/fluent/core/utils/__init__.py +0 -7
- ansys/fluent/core/utils/data_transfer.py +3 -3
- ansys/fluent/core/utils/file_transfer_service.py +24 -15
- ansys/fluent/core/utils/fluent_version.py +4 -6
- ansys/fluent/core/utils/networking.py +21 -11
- {ansys_fluent_core-0.34.dev0.dist-info → ansys_fluent_core-0.35.dev0.dist-info}/METADATA +10 -11
- {ansys_fluent_core-0.34.dev0.dist-info → ansys_fluent_core-0.35.dev0.dist-info}/RECORD +108 -106
- {ansys_fluent_core-0.34.dev0.dist-info → ansys_fluent_core-0.35.dev0.dist-info}/WHEEL +1 -1
- {ansys_fluent_core-0.34.dev0.dist-info/licenses → ansys_fluent_core-0.35.dev0.dist-info}/LICENSE +0 -0
ansys/fluent/core/__init__.py
CHANGED
|
@@ -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
|
|
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.
|
|
84
|
+
__version__ = "0.35.dev0"
|
|
81
85
|
|
|
82
|
-
_VERSION_INFO = "Build date:
|
|
86
|
+
_VERSION_INFO = "Build date: August 12, 2025 05:58 UTC ShaID: c65664b"
|
|
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 = False
|
|
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
|
-
|
|
193
|
-
|
|
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
|
|
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
|
-
|
|
26
|
-
|
|
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 =
|
|
31
|
-
_PYI_FILE =
|
|
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
|
|
41
|
+
from ansys.fluent.core import config, utils
|
|
36
42
|
|
|
37
43
|
settings = utils.load_module(
|
|
38
44
|
f"settings_{version}",
|
|
39
|
-
|
|
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
|
-
|
|
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,8 +87,11 @@ 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
|
|
@@ -86,8 +104,9 @@ def generate(version: str):
|
|
|
86
104
|
if kind == "NamedObject":
|
|
87
105
|
kind = f"{final_type}NamedObject"
|
|
88
106
|
f.write(f"class {name}(_{kind}Setting):\n")
|
|
89
|
-
doc_kind = "command" if kind == "Command" else "setting"
|
|
107
|
+
doc_kind = "command object" if kind == "Command" else "setting"
|
|
90
108
|
f.write(f' """{name} {doc_kind}."""\n\n')
|
|
109
|
+
f.write(f' _db_name = "{name}"\n\n')
|
|
91
110
|
f.write(" def __init__(self")
|
|
92
111
|
for named_object in named_objects:
|
|
93
112
|
f.write(f", {named_object}: str")
|
|
@@ -96,8 +115,6 @@ def generate(version: str):
|
|
|
96
115
|
f.write(", name: str = None")
|
|
97
116
|
elif kind == "CreatableNamedObject":
|
|
98
117
|
f.write(", name: str = None, new_instance_name: str = None")
|
|
99
|
-
if kind == "Command":
|
|
100
|
-
f.write(", **kwargs")
|
|
101
118
|
f.write("):\n")
|
|
102
119
|
f.write(" super().__init__(settings_source=settings_source")
|
|
103
120
|
if kind == "NonCreatableNamedObject":
|
|
@@ -106,9 +123,20 @@ def generate(version: str):
|
|
|
106
123
|
f.write(", name=name, new_instance_name=new_instance_name")
|
|
107
124
|
for named_object in named_objects:
|
|
108
125
|
f.write(f", {named_object}={named_object}")
|
|
109
|
-
if kind == "Command":
|
|
110
|
-
f.write(", **kwargs")
|
|
111
126
|
f.write(")\n\n")
|
|
127
|
+
if kind == "Command":
|
|
128
|
+
command_name = _convert_camel_case_to_snake_case(name)
|
|
129
|
+
f.write(f"class {command_name}(_{kind}Setting):\n")
|
|
130
|
+
f.write(f' """{command_name} command."""\n\n')
|
|
131
|
+
f.write(f' _db_name = "{name}"\n\n')
|
|
132
|
+
f.write(
|
|
133
|
+
" def __new__(cls, settings_source: SettingsBase | Solver | None = None, **kwargs):\n"
|
|
134
|
+
)
|
|
135
|
+
f.write(" instance = super().__new__(cls)\n")
|
|
136
|
+
f.write(
|
|
137
|
+
" instance.__init__(settings_source=settings_source, **kwargs)\n"
|
|
138
|
+
)
|
|
139
|
+
f.write(" return instance(**kwargs)\n\n")
|
|
112
140
|
|
|
113
141
|
with open(_PYI_FILE, "w") as f:
|
|
114
142
|
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 = (
|
|
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
|
|
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 = (
|
|
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')
|
|
@@ -38,6 +38,7 @@ from ansys.fluent.core.solver.flobject import (
|
|
|
38
38
|
ListObject,
|
|
39
39
|
NamedObject,
|
|
40
40
|
get_cls,
|
|
41
|
+
to_constant_name,
|
|
41
42
|
to_python_name,
|
|
42
43
|
)
|
|
43
44
|
from ansys.fluent.core.utils.fix_doc import fix_settings_doc
|
|
@@ -107,10 +108,11 @@ def strip_parameters(docstring: str) -> str:
|
|
|
107
108
|
|
|
108
109
|
|
|
109
110
|
def _populate_data(cls, api_tree: dict, version: str) -> dict:
|
|
110
|
-
data = {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
data = {
|
|
112
|
+
"version": version,
|
|
113
|
+
"name": cls.__name__,
|
|
114
|
+
"bases": [base.__name__ for base in cls.__bases__],
|
|
115
|
+
}
|
|
114
116
|
if "command" in cls.__doc__:
|
|
115
117
|
data["doc"] = strip_parameters(cls.__doc__)
|
|
116
118
|
else:
|
|
@@ -150,6 +152,7 @@ def _populate_data(cls, api_tree: dict, version: str) -> dict:
|
|
|
150
152
|
data["child_object_type"]["doc"] = f"'child_object_type' of {cls.__name__}."
|
|
151
153
|
else:
|
|
152
154
|
data["child_object_type"] = None
|
|
155
|
+
data["allowed_values"] = getattr(cls, "_allowed_values", [])
|
|
153
156
|
return data
|
|
154
157
|
|
|
155
158
|
|
|
@@ -306,7 +309,15 @@ def _write_data(cls_name: str, python_name: str, data: dict, f: IO, f_stub: IO |
|
|
|
306
309
|
if return_type:
|
|
307
310
|
s.write(f" return_type = {return_type!r}\n")
|
|
308
311
|
s_stub.write(" return_type: str\n")
|
|
312
|
+
for allowed_value in data["allowed_values"]:
|
|
313
|
+
s.write(
|
|
314
|
+
f" {to_constant_name(allowed_value)} = _FlStringConstant({allowed_value!r})\n"
|
|
315
|
+
)
|
|
316
|
+
s_stub.write(
|
|
317
|
+
f" {to_constant_name(allowed_value)}: Final[str] = {allowed_value!r}\n"
|
|
318
|
+
)
|
|
309
319
|
s.write("\n")
|
|
320
|
+
s_stub.write("\n")
|
|
310
321
|
for name, (python_name, data, hash_, should_write_stub) in classes_to_write.items():
|
|
311
322
|
if name not in _CLASS_WRITTEN:
|
|
312
323
|
_write_data(
|
|
@@ -344,7 +355,7 @@ def generate(version: str, static_infos: dict, verbose: bool = False) -> None:
|
|
|
344
355
|
shash = _gethash(sinfo)
|
|
345
356
|
if not sinfo:
|
|
346
357
|
return {"<solver_session>": api_tree}
|
|
347
|
-
output_dir = (pyfluent.
|
|
358
|
+
output_dir = (pyfluent.config.codegen_outdir / "solver").resolve()
|
|
348
359
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
349
360
|
output_file = output_dir / f"settings_{version}.py"
|
|
350
361
|
output_stub_file = output_dir / f"settings_{version}.pyi"
|
|
@@ -370,10 +381,11 @@ def generate(version: str, static_infos: dict, verbose: bool = False) -> None:
|
|
|
370
381
|
header.write(" _InputFile,\n")
|
|
371
382
|
header.write(" _OutputFile,\n")
|
|
372
383
|
header.write(" _InOutFile,\n")
|
|
384
|
+
header.write(" _FlStringConstant,\n")
|
|
373
385
|
header.write(")\n\n")
|
|
374
386
|
f.write(header.getvalue())
|
|
375
387
|
f_stub.write(header.getvalue())
|
|
376
|
-
f_stub.write("from typing import Any\n\n")
|
|
388
|
+
f_stub.write("from typing import Any, Final\n\n")
|
|
377
389
|
f.write(f'SHASH = "{shash}"\n\n')
|
|
378
390
|
name = data["name"]
|
|
379
391
|
_NAME_BY_HASH[_gethash(data)] = name
|
|
@@ -52,6 +52,7 @@ import ansys.fluent.core as pyfluent
|
|
|
52
52
|
from ansys.fluent.core import FluentMode, launch_fluent
|
|
53
53
|
from ansys.fluent.core.codegen import StaticInfoType
|
|
54
54
|
from ansys.fluent.core.codegen.data.fluent_gui_help_patch import XML_HELP_PATCH
|
|
55
|
+
from ansys.fluent.core.docker.utils import get_ghcr_fluent_image_name
|
|
55
56
|
from ansys.fluent.core.services.datamodel_tui import (
|
|
56
57
|
convert_path_to_grpc_path,
|
|
57
58
|
convert_tui_menu_to_func_name,
|
|
@@ -68,7 +69,7 @@ _ROOT_DIR = Path(__file__) / ".." / ".." / ".." / ".." / ".." / ".."
|
|
|
68
69
|
|
|
69
70
|
|
|
70
71
|
def _get_tui_filepath(mode: str, version: str):
|
|
71
|
-
return (pyfluent.
|
|
72
|
+
return (pyfluent.config.codegen_outdir / mode / f"tui_{version}.py").resolve()
|
|
72
73
|
|
|
73
74
|
|
|
74
75
|
_INDENT_STEP = 4
|
|
@@ -95,9 +96,9 @@ _XML_HELPSTRINGS = {}
|
|
|
95
96
|
|
|
96
97
|
|
|
97
98
|
def _copy_tui_help_xml_file(version: str):
|
|
98
|
-
if
|
|
99
|
-
image_tag =
|
|
100
|
-
image_name = f"
|
|
99
|
+
if pyfluent.config.launch_fluent_container:
|
|
100
|
+
image_tag = pyfluent.config.fluent_image_tag
|
|
101
|
+
image_name = f"{get_ghcr_fluent_image_name(image_tag)}:{image_tag}"
|
|
101
102
|
container_name = uuid.uuid4().hex
|
|
102
103
|
is_linux = platform.system() == "Linux"
|
|
103
104
|
subprocess.run(
|
|
@@ -346,7 +347,7 @@ def generate(version, static_infos: dict, verbose: bool = False):
|
|
|
346
347
|
api_tree["<solver_session>"] = TUIGenerator(
|
|
347
348
|
"solver", version, static_infos, verbose
|
|
348
349
|
).generate()
|
|
349
|
-
if
|
|
350
|
+
if not pyfluent.config.hide_log_secrets:
|
|
350
351
|
logger.info(
|
|
351
352
|
"XML help is available but not picked for the following %i paths: ",
|
|
352
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
|
|
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,
|
|
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,29 +22,31 @@
|
|
|
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
|
|
|
28
|
+
from .utils import get_ghcr_fluent_image_name
|
|
29
|
+
|
|
29
30
|
|
|
30
31
|
class ComposeBasedLauncher:
|
|
31
32
|
"""Launch Fluent through docker or Podman compose."""
|
|
32
33
|
|
|
33
|
-
def __init__(self,
|
|
34
|
+
def __init__(self, compose_config, container_dict):
|
|
35
|
+
from ansys.fluent.core import config
|
|
36
|
+
|
|
37
|
+
self._compose_config = compose_config
|
|
34
38
|
self._compose_name = f"pyfluent_compose_{uuid.uuid4().hex}"
|
|
35
39
|
self._container_dict = container_dict
|
|
40
|
+
image_tag = config.fluent_image_tag
|
|
36
41
|
self._image_name = (
|
|
37
42
|
container_dict.get("fluent_image")
|
|
38
|
-
or f"
|
|
43
|
+
or f"{get_ghcr_fluent_image_name(image_tag)}:{image_tag}"
|
|
39
44
|
)
|
|
40
45
|
self._container_source = self._set_compose_cmds()
|
|
41
46
|
self._container_source.remove("compose")
|
|
42
47
|
|
|
43
48
|
self._compose_file = self._get_compose_file(container_dict)
|
|
44
49
|
|
|
45
|
-
def _is_podman_selected(self):
|
|
46
|
-
return os.getenv("PYFLUENT_USE_PODMAN_COMPOSE") == "1"
|
|
47
|
-
|
|
48
50
|
def _get_compose_file(self, container_dict):
|
|
49
51
|
"""Generates compose file for the Docker Compose setup.
|
|
50
52
|
|
|
@@ -129,14 +131,14 @@ class ComposeBasedLauncher:
|
|
|
129
131
|
"""
|
|
130
132
|
|
|
131
133
|
# Determine the compose command
|
|
132
|
-
if
|
|
134
|
+
if self._compose_config.use_podman_compose:
|
|
133
135
|
self._compose_cmds = (
|
|
134
136
|
["sudo", "podman", "compose"]
|
|
135
137
|
if hasattr(self, "_container_source")
|
|
136
138
|
and "sudo" in self._container_source
|
|
137
139
|
else ["podman", "compose"]
|
|
138
140
|
)
|
|
139
|
-
elif
|
|
141
|
+
elif self._compose_config.use_docker_compose:
|
|
140
142
|
self._compose_cmds = ["docker", "compose"]
|
|
141
143
|
else:
|
|
142
144
|
raise RuntimeError("Neither Docker nor Podman is specified.")
|
|
@@ -148,7 +150,7 @@ class ComposeBasedLauncher:
|
|
|
148
150
|
try:
|
|
149
151
|
cmd = self._container_source + ["images", "-q", self._image_name]
|
|
150
152
|
# Podman users do not always configure rootless mode in /etc/subuids and /etc/subgids
|
|
151
|
-
if self.
|
|
153
|
+
if self._compose_config.use_podman_compose:
|
|
152
154
|
sudo_cmd = ["sudo"] + cmd
|
|
153
155
|
output_1 = subprocess.check_output(cmd)
|
|
154
156
|
output_2 = subprocess.check_output(sudo_cmd)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
Utility functions for working with Fluent Docker images.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_ghcr_fluent_image_name(image_tag: str):
|
|
29
|
+
"""
|
|
30
|
+
Get the Fluent image name from GitHub registry based on the image tag.
|
|
31
|
+
"""
|
|
32
|
+
if image_tag.startswith("sha256:") or image_tag >= "v26.1":
|
|
33
|
+
return "ghcr.io/ansys/fluent"
|
|
34
|
+
else:
|
|
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.
|
|
52
|
+
The default examples path is given by ``pyfluent.config.examples_path``.
|
|
53
53
|
"""
|
|
54
|
-
shutil.rmtree(pyfluent.
|
|
55
|
-
os.makedirs(pyfluent.
|
|
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.
|
|
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.
|
|
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)
|
|
@@ -180,8 +177,8 @@ def download_file(
|
|
|
180
177
|
'bracket.iges'
|
|
181
178
|
"""
|
|
182
179
|
if return_without_path is None:
|
|
183
|
-
if
|
|
184
|
-
if pyfluent.
|
|
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.
|
|
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:
|
ansys/fluent/core/exceptions.py
CHANGED
|
@@ -34,7 +34,7 @@ class DisallowedValuesError(ValueError):
|
|
|
34
34
|
context: str | None = None,
|
|
35
35
|
name: Any | None = None,
|
|
36
36
|
allowed_values: Iterable[Any] | None = None,
|
|
37
|
-
):
|
|
37
|
+
) -> None:
|
|
38
38
|
"""Initialize DisallowedValuesError."""
|
|
39
39
|
super().__init__(
|
|
40
40
|
allowed_name_error_message(
|
|
@@ -50,3 +50,15 @@ class InvalidArgument(ValueError):
|
|
|
50
50
|
"""Raised when an argument value is inappropriate."""
|
|
51
51
|
|
|
52
52
|
pass
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class BetaFeaturesNotEnabled(RuntimeError):
|
|
56
|
+
"""Raised when a beta feature is accessed without enabling beta features."""
|
|
57
|
+
|
|
58
|
+
def __init__(self, feature_name: str | None = None) -> None:
|
|
59
|
+
message = (
|
|
60
|
+
f"The feature '{feature_name}' is not available until 'enable_beta_features()' has been called."
|
|
61
|
+
if feature_name
|
|
62
|
+
else "This feature is not available until 'enable_beta_features()' has been called."
|
|
63
|
+
)
|
|
64
|
+
super().__init__(message)
|