ansys-fluent-core 0.35.dev0__py3-none-any.whl → 0.36.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 (73) hide show
  1. ansys/fluent/core/__init__.py +2 -2
  2. ansys/fluent/core/codegen/__init__.py +1 -0
  3. ansys/fluent/core/codegen/builtin_settingsgen.py +4 -0
  4. ansys/fluent/core/codegen/datamodelgen.py +13 -2
  5. ansys/fluent/core/codegen/settingsgen.py +7 -0
  6. ansys/fluent/core/docker/docker_compose.py +30 -1
  7. ansys/fluent/core/examples/downloads.py +3 -4
  8. ansys/fluent/core/fluent_connection.py +2 -3
  9. ansys/fluent/core/generated/api_tree/api_objects.json +1 -1
  10. ansys/fluent/core/generated/datamodel_231/flicing.py +20 -20
  11. ansys/fluent/core/generated/datamodel_231/meshing.py +236 -236
  12. ansys/fluent/core/generated/datamodel_232/flicing.py +50 -50
  13. ansys/fluent/core/generated/datamodel_232/meshing.py +187 -187
  14. ansys/fluent/core/generated/datamodel_241/flicing.py +45 -45
  15. ansys/fluent/core/generated/datamodel_241/meshing.py +229 -229
  16. ansys/fluent/core/generated/datamodel_242/flicing.py +50 -50
  17. ansys/fluent/core/generated/datamodel_242/meshing.py +275 -275
  18. ansys/fluent/core/generated/datamodel_242/part_management.py +3 -3
  19. ansys/fluent/core/generated/datamodel_251/flicing.py +45 -45
  20. ansys/fluent/core/generated/datamodel_251/meshing.py +417 -417
  21. ansys/fluent/core/generated/datamodel_251/part_management.py +9 -9
  22. ansys/fluent/core/generated/datamodel_252/flicing.py +30 -30
  23. ansys/fluent/core/generated/datamodel_252/meshing.py +418 -418
  24. ansys/fluent/core/generated/datamodel_252/part_management.py +5 -5
  25. ansys/fluent/core/generated/datamodel_261/flicing.py +35 -35
  26. ansys/fluent/core/generated/datamodel_261/meshing.py +481 -425
  27. ansys/fluent/core/generated/datamodel_261/meshing_utilities.py +296 -616
  28. ansys/fluent/core/generated/datamodel_261/meshing_workflow.py +61694 -0
  29. ansys/fluent/core/generated/datamodel_261/part_management.py +10 -10
  30. ansys/fluent/core/generated/datamodel_261/preferences.py +56 -0
  31. ansys/fluent/core/generated/datamodel_261/solver_workflow.py +14 -0
  32. ansys/fluent/core/generated/fluent_version_261.py +3 -3
  33. ansys/fluent/core/generated/meshing/tui_261.py +408 -10
  34. ansys/fluent/core/generated/solver/settings_261.py +15135 -5725
  35. ansys/fluent/core/generated/solver/settings_261.pyi +10252 -3619
  36. ansys/fluent/core/generated/solver/tui_261.py +2632 -834
  37. ansys/fluent/core/launcher/container_launcher.py +12 -3
  38. ansys/fluent/core/launcher/fluent_container.py +7 -1
  39. ansys/fluent/core/launcher/launch_options.py +2 -2
  40. ansys/fluent/core/launcher/launcher.py +2 -6
  41. ansys/fluent/core/launcher/pim_launcher.py +76 -3
  42. ansys/fluent/core/launcher/process_launch_string.py +1 -2
  43. ansys/fluent/core/launcher/slurm_launcher.py +4 -3
  44. ansys/fluent/core/launcher/standalone_launcher.py +3 -2
  45. ansys/fluent/core/module_config.py +10 -10
  46. ansys/fluent/core/report.py +1 -1
  47. ansys/fluent/core/search.py +12 -0
  48. ansys/fluent/core/services/__init__.py +2 -0
  49. ansys/fluent/core/services/datamodel_se.py +4 -1
  50. ansys/fluent/core/services/field_data.py +24 -0
  51. ansys/fluent/core/services/reduction.py +2 -0
  52. ansys/fluent/core/services/settings.py +1 -1
  53. ansys/fluent/core/services/solution_variables.py +92 -0
  54. ansys/fluent/core/session.py +1 -2
  55. ansys/fluent/core/session_base_meshing.py +8 -0
  56. ansys/fluent/core/session_meshing.py +5 -0
  57. ansys/fluent/core/session_pure_meshing.py +6 -0
  58. ansys/fluent/core/session_pure_meshing.pyi +5 -0
  59. ansys/fluent/core/session_solver.py +5 -4
  60. ansys/fluent/core/session_utilities.py +8 -5
  61. ansys/fluent/core/solver/flobject.py +19 -0
  62. ansys/fluent/core/solver/flunits.py +2 -0
  63. ansys/fluent/core/solver/function/reduction.py +2 -0
  64. ansys/fluent/core/ui/__init__.py +64 -0
  65. ansys/fluent/core/ui/jupyter_ui.py +203 -0
  66. ansys/fluent/core/ui/standalone_web_ui.py +296 -0
  67. ansys/fluent/core/ui/utils.py +173 -0
  68. ansys/fluent/core/utils/deprecate.py +1 -0
  69. ansys/fluent/core/utils/networking.py +11 -2
  70. {ansys_fluent_core-0.35.dev0.dist-info → ansys_fluent_core-0.36.dev0.dist-info}/METADATA +29 -22
  71. {ansys_fluent_core-0.35.dev0.dist-info → ansys_fluent_core-0.36.dev0.dist-info}/RECORD +73 -68
  72. {ansys_fluent_core-0.35.dev0.dist-info → ansys_fluent_core-0.36.dev0.dist-info}/WHEEL +1 -1
  73. {ansys_fluent_core-0.35.dev0.dist-info → ansys_fluent_core-0.36.dev0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,296 @@
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
+ """Web UI for Fluent settings using Panel with lazy loading and batched property access."""
24
+
25
+ from __future__ import annotations
26
+
27
+ from typing import Any, Callable, Dict, List
28
+
29
+ try:
30
+ import panel as pn
31
+ import param
32
+ except ModuleNotFoundError as exc:
33
+ raise ModuleNotFoundError(
34
+ "Missing dependencies, use 'pip install ansys-fluent-core[ui]' to install them."
35
+ ) from exc
36
+
37
+ from ansys.fluent.core.solver.flobject import (
38
+ BaseCommand,
39
+ Group,
40
+ NamedObject,
41
+ )
42
+ from ansys.fluent.core.ui.utils import (
43
+ _parse_path,
44
+ _render_widget_from_props_generic,
45
+ _safe_get_properties,
46
+ )
47
+
48
+ _path_backup_dict = {}
49
+
50
+ AUTO_REFRESH = False
51
+
52
+
53
+ def set_auto_refresh():
54
+ """Refreshes the UI w.r.t. server state for each command execution or parameter invocation."""
55
+ global AUTO_REFRESH
56
+ AUTO_REFRESH = True
57
+
58
+
59
+ pn.extension()
60
+
61
+ # global trigger for refresh (Panel Param depends on it)
62
+ _refresh = pn.state.cache.get("fluent_refresh", None)
63
+ if _refresh is None:
64
+
65
+ class Refresh(param.Parameterized):
66
+ """Refresh."""
67
+
68
+ bump = param.Event()
69
+
70
+ _refresh = Refresh()
71
+ pn.state.cache["fluent_refresh"] = _refresh
72
+
73
+
74
+ def _render_widget_from_props(
75
+ settings_obj, label: str, props: Dict[str, Any]
76
+ ) -> pn.viewable.Viewable:
77
+ """Produce a Panel widget from type+props. No backend mutation here."""
78
+ return _render_widget_from_props_generic(settings_obj, label, props, pn.widgets)
79
+
80
+
81
+ def _param_view(settings_obj, props: Dict[str, Any]) -> pn.viewable.Viewable:
82
+ label = props["python_name"].replace("_", " ").capitalize()
83
+
84
+ def get_fn():
85
+ try:
86
+ return getattr(props["parent"], props["python_name"])
87
+ except AttributeError:
88
+ return props["parent"][props["obj_name"]]
89
+
90
+ def set_fn(v):
91
+ return setattr(settings_obj.parent, props["python_name"], v)
92
+
93
+ w = _render_widget_from_props(get_fn(), label, props)
94
+ obj_apth = _parse_path(settings_obj)
95
+ if obj_apth in _path_backup_dict:
96
+ console = pn.pane.Markdown(
97
+ f"```\n{obj_apth} = {_path_backup_dict[obj_apth]}\n```",
98
+ sizing_mode="stretch_width",
99
+ )
100
+ else:
101
+ console = pn.pane.Markdown(f"```\n{obj_apth}\n```", sizing_mode="stretch_width")
102
+
103
+ # Change handlers
104
+ if hasattr(w, "_is_list_text"):
105
+ typ, parse_csv = w._is_list_text
106
+
107
+ def _commit_list(event):
108
+ if event is None:
109
+ return
110
+ newv = event.new
111
+ if parse_csv:
112
+ raw = newv or ""
113
+ vals = [typ(v.strip()) for v in raw.split(",") if v.strip()]
114
+ else:
115
+ vals = list(newv or [])
116
+ try:
117
+ set_fn(vals)
118
+ console.object = f"```\n{_parse_path(settings_obj)} = {vals}\n```"
119
+ _path_backup_dict[_parse_path(settings_obj)] = vals
120
+ if AUTO_REFRESH:
121
+ _refresh.bump = True
122
+ except Exception as e:
123
+ console.object = f"```\nError setting {label}: {e}\n```"
124
+
125
+ w.param.watch(_commit_list, "value", onlychanged=True)
126
+ else:
127
+
128
+ def _commit(event):
129
+ if event is None:
130
+ return
131
+ try:
132
+ set_fn(event.new)
133
+ console.object = f"```\n{_parse_path(settings_obj)} = {event.new}\n```"
134
+ _path_backup_dict[_parse_path(settings_obj)] = event.new
135
+ if AUTO_REFRESH:
136
+ _refresh.bump = True
137
+ except Exception as e:
138
+ console.object = f"```\nError setting {label}: {e}\n```"
139
+
140
+ w.param.watch(_commit, "value", onlychanged=True)
141
+
142
+ return pn.Column(
143
+ w, console, sizing_mode="stretch_width", margin=(10, 20), align="start"
144
+ )
145
+
146
+
147
+ def _command_view(func, props: Dict[str, Any]) -> pn.viewable.Viewable:
148
+ """Render command arguments (on demand) and execute only on click."""
149
+ # Safely fetch argument names (does NOT execute the command)
150
+ if not hasattr(func, "argument_names"):
151
+ return pn.pane.HTML("<i>Command has no 'argument_names()'.</i>")
152
+ arg_names = func.argument_names
153
+ arg_widgets: Dict[str, Any] = {}
154
+ controls: List[pn.viewable.Viewable] = []
155
+
156
+ # Build argument widgets immediately when this view is created
157
+ for name in arg_names:
158
+ param_obj = getattr(func, name) # safe: this just references the arg handle
159
+ pprops = _safe_get_properties(param_obj)
160
+ widget = _render_widget_from_props(param_obj, name, pprops)
161
+ arg_widgets[name] = widget
162
+ controls.append(widget)
163
+
164
+ btn = pn.widgets.Button(name=f"Run {props['python_name']}", button_type="success")
165
+ obj_path = _parse_path(func)
166
+ if obj_path in _path_backup_dict:
167
+ console = pn.pane.Markdown(
168
+ f"```\n{_path_backup_dict[obj_path]}\n```", sizing_mode="stretch_width"
169
+ )
170
+ else:
171
+ console = pn.pane.Markdown(f"```\n{obj_path}\n```", sizing_mode="stretch_width")
172
+
173
+ def _run(_):
174
+ kwargs = {n: w.value for n, w in arg_widgets.items()}
175
+ try:
176
+ func(**kwargs) # Executes ONLY here
177
+ # Render kwargs similarly to your ipywidgets formatter
178
+ parts = []
179
+ for k, v in kwargs.items():
180
+ if isinstance(v, str):
181
+ if v != "":
182
+ parts.append(f"{k}='{v}'")
183
+ else:
184
+ parts.append(f"{k}={v}")
185
+ call = f"{_parse_path(func)}({', '.join(parts)})"
186
+ console.object = f"```\n{call}\n```"
187
+ _path_backup_dict[_parse_path(func)] = call
188
+ if AUTO_REFRESH:
189
+ _refresh.bump = True
190
+ except Exception as e:
191
+ console.object = f"```\nError: {e}\n```"
192
+
193
+ btn.on_click(_run)
194
+ return pn.Column(
195
+ *controls,
196
+ btn,
197
+ console,
198
+ sizing_mode="stretch_width",
199
+ margin=(10, 20),
200
+ align="start",
201
+ )
202
+
203
+
204
+ # ---------------------------
205
+ # Lazy accordion (recursive)
206
+ # ---------------------------
207
+
208
+
209
+ def _lazy_section(
210
+ title: str, loader: Callable[[], pn.viewable.Viewable]
211
+ ) -> pn.Accordion:
212
+ """
213
+ A single-node Accordion whose body is constructed ON FIRST EXPAND.
214
+ Subsequent expands reuse the existing content.
215
+ """
216
+ placeholder = pn.pane.Markdown("*(loading…)*")
217
+ acc = pn.Accordion((title, placeholder), sizing_mode="stretch_width")
218
+
219
+ def _load_content():
220
+ try:
221
+ return loader()
222
+ except Exception as e:
223
+ return pn.pane.Markdown(f"**Error loading section**: {e}")
224
+
225
+ def _maybe_load(event=None):
226
+ if acc.active and 0 in acc.active:
227
+ content = _load_content()
228
+ acc[0] = (title, content)
229
+
230
+ # Trigger when first opened
231
+ acc.param.watch(_maybe_load, "active", onlychanged=True)
232
+
233
+ def _on_refresh(event):
234
+ if acc.active and 0 in acc.active:
235
+ _maybe_load()
236
+
237
+ _refresh.param.watch(_on_refresh, "bump")
238
+
239
+ return acc
240
+
241
+
242
+ # ---------------------------
243
+ # Main entry (recursive renderer)
244
+ # ---------------------------
245
+
246
+
247
+ def _settings_view(obj, indent: int = 0) -> pn.viewable.Viewable:
248
+ """Recursively build the view for a settings object (lazy children)."""
249
+ props = _safe_get_properties(obj)
250
+
251
+ if isinstance(obj, (Group, NamedObject)):
252
+ if isinstance(obj, Group):
253
+ command_names = obj.get_active_command_names()
254
+ child_names = obj.get_active_child_names() + command_names
255
+ else:
256
+ command_names = obj.command_names
257
+ child_names = list(obj) + command_names
258
+ else:
259
+ if isinstance(obj, BaseCommand):
260
+ return _command_view(obj, props) if props["is_active"] else pn.pane.HTML("")
261
+ else:
262
+ return _param_view(obj, props) if props["is_active"] else pn.pane.HTML("")
263
+
264
+ sections: List[pn.viewable.Viewable] = []
265
+
266
+ for child_name in child_names:
267
+ # Build a lazy loader that only resolves the child on expand
268
+ def _loader(name=child_name, parent=obj, lvl=indent + 1):
269
+ try:
270
+ child_obj = getattr(parent, name)
271
+ except AttributeError:
272
+ child_obj = parent[name]
273
+ return _settings_view(child_obj, lvl)
274
+
275
+ # Each child gets its own one-item accordion (mirrors your ipywidgets UX)
276
+ if child_name in command_names:
277
+ display_name = f"⚡ {child_name}"
278
+ else:
279
+ display_name = child_name
280
+ sections.append(_lazy_section(display_name, _loader))
281
+
282
+ return pn.Column(
283
+ *(pn.Column(sec, margin=(5, 0)) for sec in sections),
284
+ sizing_mode="fixed",
285
+ margin=(10, 20),
286
+ align="start",
287
+ css_classes=["rounded-box"],
288
+ )
289
+
290
+
291
+ def build_settings_view(settings_obj) -> pn.viewable.Viewable:
292
+ """
293
+ Public API: pass any Fluent settings object.
294
+ Internally uses _root to render absolute paths and builds a lazy, web UI.
295
+ """
296
+ return _settings_view(settings_obj)
@@ -0,0 +1,173 @@
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
+ """Utilities methods for ui rendering."""
24
+
25
+ from ansys.fluent.core.solver.flobject import (
26
+ BaseCommand,
27
+ Boolean,
28
+ Integer,
29
+ IntegerList,
30
+ NamedObject,
31
+ Real,
32
+ RealList,
33
+ String,
34
+ StringList,
35
+ )
36
+ from ansys.fluent.core.ui import in_jupyter
37
+
38
+
39
+ def _parse_path(settings_obj):
40
+ """Convert a settings object path to a string representation
41
+ with proper indexing for NamedObject keys."""
42
+ local_obj = settings_obj._root
43
+ path_str = "<solver_session>.settings."
44
+ for path in settings_obj.path.replace("/", ".").replace("?", "").split("."):
45
+ py_path = path.replace("-", "_")
46
+ if not path:
47
+ break
48
+ if isinstance(local_obj, NamedObject):
49
+ try:
50
+ local_obj = local_obj[path]
51
+ path_str = path_str[:-1] + f"['{path}']" + "."
52
+ except KeyError:
53
+ local_obj = getattr(local_obj, py_path)
54
+ path_str += f"{py_path}."
55
+ else:
56
+ local_obj = getattr(local_obj, py_path)
57
+ path_str += f"{py_path}."
58
+
59
+ return path_str[:-1]
60
+
61
+
62
+ def _safe_get_properties(settings_obj):
63
+ """Fetch potentially expensive properties once."""
64
+ props = {}
65
+ try:
66
+ props["is_active"] = settings_obj.is_active()
67
+ except RuntimeError:
68
+ props["is_active"] = False
69
+
70
+ try:
71
+ if isinstance(settings_obj, BaseCommand):
72
+ props["value"] = ""
73
+ else:
74
+ props["value"] = settings_obj() if props["is_active"] else ""
75
+ except RuntimeError:
76
+ props["value"] = ""
77
+
78
+ props["allowed_values"] = None
79
+ if hasattr(settings_obj, "allowed_values"):
80
+ try:
81
+ av = settings_obj.allowed_values()
82
+ props["allowed_values"] = list(av) if av else None
83
+ except RuntimeError:
84
+ pass
85
+
86
+ props["path"] = getattr(settings_obj, "path", "")
87
+ props["python_name"] = getattr(settings_obj, "python_name", "")
88
+ props["obj_name"] = getattr(settings_obj, "obj_name", "")
89
+ props["parent"] = getattr(settings_obj, "parent", None)
90
+ return props
91
+
92
+
93
+ def _render_widget_from_props_generic(
94
+ settings_obj, label: str, props: dict, parent_widget
95
+ ):
96
+ """
97
+ Render a widget from type+props using either ipywidgets or Panel.
98
+ """
99
+ if in_jupyter():
100
+ widget_map = {
101
+ "bool": lambda v: parent_widget.Checkbox(
102
+ value=v, description=label, indent=False
103
+ ),
104
+ "int": lambda v: parent_widget.IntText(value=v, description=label),
105
+ "float": lambda v: parent_widget.FloatText(value=v, description=label),
106
+ "text": lambda v: parent_widget.Text(value=v, description=label),
107
+ "select": lambda opts, v: parent_widget.Dropdown(
108
+ options=opts, value=v, description=label
109
+ ),
110
+ "multi": lambda opts, v: parent_widget.SelectMultiple(
111
+ options=opts, value=v, description=label
112
+ ),
113
+ }
114
+ else:
115
+ widget_map = {
116
+ "bool": lambda v: parent_widget.Checkbox(name=label, value=v),
117
+ "int": lambda v: parent_widget.IntInput(name=label, value=v),
118
+ "float": lambda v: parent_widget.FloatInput(name=label, value=v),
119
+ "text": lambda v: parent_widget.TextInput(name=label, value=v),
120
+ "select": lambda opts, v: parent_widget.Select(
121
+ name=label, options=opts, value=v
122
+ ),
123
+ "multi": lambda opts, v: parent_widget.MultiChoice(
124
+ name=label, options=opts, value=v
125
+ ),
126
+ }
127
+
128
+ settings_val = props.get("value")
129
+ allowed = props.get("allowed_values")
130
+
131
+ try:
132
+ if isinstance(settings_obj, Boolean):
133
+ return widget_map["bool"](bool(settings_val))
134
+ elif isinstance(settings_obj, Integer):
135
+ return widget_map["int"](int(settings_val))
136
+ elif isinstance(settings_obj, Real):
137
+ return widget_map["float"](float(settings_val))
138
+ elif isinstance(settings_obj, String):
139
+ if allowed:
140
+ options = [str(v) for v in allowed]
141
+ val = str(settings_val)
142
+ if val not in options:
143
+ val = options[0]
144
+ return widget_map["select"](options, val)
145
+ else:
146
+ if settings_val is False:
147
+ settings_val = ""
148
+ return widget_map["text"](str(settings_val))
149
+ elif isinstance(settings_obj, StringList):
150
+ if allowed:
151
+ options = [str(v) for v in allowed]
152
+ current = [str(v) for v in (settings_val or []) if str(v) in options]
153
+ w = widget_map["multi"](options, current)
154
+ w._is_list_text = (str, False)
155
+ return w
156
+ else:
157
+ w = widget_map["text"](",".join(map(str, settings_val or [])))
158
+ w._is_list_text = (str, True)
159
+ return w
160
+ elif isinstance(settings_obj, IntegerList):
161
+ w = widget_map["text"](",".join(map(str, settings_val or [])))
162
+ w._is_list_text = (int, True)
163
+ return w
164
+ elif isinstance(settings_obj, RealList):
165
+ w = widget_map["text"](",".join(map(str, settings_val or [])))
166
+ w._is_list_text = (float, True)
167
+ return w
168
+ else:
169
+ if settings_val is False:
170
+ settings_val = ""
171
+ return widget_map["text"](str(settings_val))
172
+ except ValueError:
173
+ return widget_map["text"](str(settings_val))
@@ -34,6 +34,7 @@ from ansys.fluent.core.pyfluent_warnings import PyFluentDeprecationWarning
34
34
  logger = logging.getLogger("pyfluent.general")
35
35
 
36
36
 
37
+ # TODO: Refactor 'all_deprecators' to remove boilerplate code from implementation
37
38
  def all_deprecators(
38
39
  deprecate_arg_mappings,
39
40
  data_type_converter,
@@ -25,6 +25,7 @@
25
25
  from concurrent import futures
26
26
  import logging
27
27
  import socket
28
+ import ssl
28
29
  from typing import Any
29
30
  import urllib.request
30
31
 
@@ -130,12 +131,20 @@ def check_url_exists(url: str) -> bool:
130
131
  -------
131
132
  bool
132
133
  True if the URL exists, False otherwise
134
+
135
+ Raises
136
+ ------
137
+ ssl.SSLError
138
+ If there is an SSL error while checking the URL
133
139
  """
134
140
  try:
135
141
  with urllib.request.urlopen(url) as response:
136
142
  return response.status == 200
137
- except Exception:
138
- return False
143
+ except urllib.error.URLError as ex:
144
+ if ex.__context__ and isinstance(ex.__context__, ssl.SSLError):
145
+ raise ex.__context__
146
+ else:
147
+ return False
139
148
 
140
149
 
141
150
  def get_url_content(url: str) -> str:
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: ansys-fluent-core
3
- Version: 0.35.dev0
3
+ Version: 0.36.dev0
4
4
  Summary: PyFluent provides Pythonic access to Ansys Fluent.
5
5
  Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
6
6
  Maintainer-email: "ANSYS, Inc." <pyansys.core@ansys.com>
@@ -10,10 +10,11 @@ Classifier: Development Status :: 4 - Beta
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: License :: OSI Approved :: MIT License
12
12
  Classifier: Operating System :: OS Independent
13
+ License-File: LICENSE
13
14
  Requires-Dist: ansys-api-fluent>=0.3.36
14
15
  Requires-Dist: ansys-platform-instancemanagement~=1.1
15
16
  Requires-Dist: ansys-tools-filetransfer>=0.1,<0.3
16
- Requires-Dist: ansys-units>=0.7.0,<1.0
17
+ Requires-Dist: ansys-units>=0.8.1,<1.0
17
18
  Requires-Dist: defusedxml>=0.7.1
18
19
  Requires-Dist: deprecated>=1.2.18
19
20
  Requires-Dist: docker>=7.1.0
@@ -28,8 +29,8 @@ Requires-Dist: pyyaml>=6.0
28
29
  Requires-Dist: Sphinx==8.1.3 ; extra == "docs"
29
30
  Requires-Dist: jupyter_sphinx==0.5.3 ; extra == "docs"
30
31
  Requires-Dist: numpydoc==1.9.0 ; extra == "docs"
31
- Requires-Dist: matplotlib==3.10.3 ; extra == "docs"
32
- Requires-Dist: ansys-sphinx-theme==1.5.2 ; extra == "docs"
32
+ Requires-Dist: matplotlib==3.10.6 ; extra == "docs"
33
+ Requires-Dist: ansys-sphinx-theme==1.6.1 ; extra == "docs"
33
34
  Requires-Dist: pypandoc==1.15 ; extra == "docs"
34
35
  Requires-Dist: pytest-sphinx==0.6.3 ; extra == "docs"
35
36
  Requires-Dist: sphinx-autobuild==2024.10.3 ; extra == "docs"
@@ -38,28 +39,33 @@ Requires-Dist: sphinx-copybutton==0.5.2 ; extra == "docs"
38
39
  Requires-Dist: sphinx-gallery==0.19.0 ; extra == "docs"
39
40
  Requires-Dist: sphinx-notfound-page==1.1.0 ; extra == "docs"
40
41
  Requires-Dist: sphinxcontrib-websupport==2.0.0 ; extra == "docs"
42
+ Requires-Dist: sphinx_design==0.6.1 ; extra == "docs"
41
43
  Requires-Dist: sphinxemoji==0.3.1 ; extra == "docs"
42
44
  Requires-Dist: sphinx-toggleprompt==0.6.0 ; extra == "docs"
43
45
  Requires-Dist: autodocsumm==0.2.14 ; extra == "docs"
44
- Requires-Dist: beautifulsoup4==4.13.4 ; extra == "docs"
46
+ Requires-Dist: beautifulsoup4==4.14.2 ; extra == "docs"
45
47
  Requires-Dist: openpyxl>=3.1.5 ; extra == "docs"
46
48
  Requires-Dist: plotly>=5.22.0 ; extra == "docs"
47
49
  Requires-Dist: python-pptx>=0.6.23 ; extra == "docs"
48
- Requires-Dist: quarto-cli==1.7.32 ; extra == "docs"
50
+ Requires-Dist: quarto-cli==1.8.25 ; extra == "docs"
49
51
  Requires-Dist: pdf2image==1.17.0 ; extra == "docs"
50
52
  Requires-Dist: seaborn>=0.13.2 ; extra == "docs"
51
53
  Requires-Dist: h5py==3.14.0 ; extra == "reader"
52
- Requires-Dist: pytest==8.4.1 ; extra == "tests"
53
- Requires-Dist: pytest-cov==6.2.1 ; extra == "tests"
54
- Requires-Dist: pytest-mock==3.14.1 ; extra == "tests"
55
- Requires-Dist: pytest-xdist==3.7.0 ; extra == "tests"
56
- Requires-Dist: pyfakefs==5.9.1 ; extra == "tests"
54
+ Requires-Dist: pytest==8.4.2 ; extra == "tests"
55
+ Requires-Dist: pytest-cov==7.0.0 ; extra == "tests"
56
+ Requires-Dist: pytest-mock==3.15.1 ; extra == "tests"
57
+ Requires-Dist: pytest-xdist==3.8.0 ; extra == "tests"
58
+ Requires-Dist: pyfakefs==5.9.3 ; extra == "tests"
59
+ Requires-Dist: panel ; extra == "ui"
60
+ Requires-Dist: ipywidgets ; extra == "ui-jupyter"
57
61
  Project-URL: Documentation, https://fluent.docs.pyansys.com/
58
62
  Project-URL: Source, https://github.com/ansys/pyfluent
59
63
  Project-URL: Tracker, https://github.com/ansys/pyfluent/issues
60
64
  Provides-Extra: docs
61
65
  Provides-Extra: reader
62
66
  Provides-Extra: tests
67
+ Provides-Extra: ui
68
+ Provides-Extra: ui-jupyter
63
69
 
64
70
  PyFluent
65
71
  ========
@@ -77,7 +83,7 @@ PyFluent
77
83
  :target: https://pypi.org/project/ansys-fluent-core
78
84
  :alt: PyPI
79
85
 
80
- .. |GH-CI| image:: https://github.com/ansys/pyfluent/actions/workflows/ci.yml/badge.svg
86
+ .. |GH-CI| image:: https://github.com/ansys/pyfluent/actions/workflows/ci.yml/badge.svg?branch=main
81
87
  :target: https://github.com/ansys/pyfluent/actions/workflows/ci.yml
82
88
  :alt: GH-CI
83
89
 
@@ -188,21 +194,22 @@ To launch Fluent from Python, use the ``launch_fluent`` function:
188
194
 
189
195
  Basic usage
190
196
  ~~~~~~~~~~~
191
- You can use the ``solver_session.tui`` interface to run all Fluent TUI commands:
197
+ The ``solver_session`` interface provides a convenient way to launch and
198
+ interact with Fluent.
192
199
 
193
200
  .. code:: python
194
201
 
195
- solver_session.tui.file.read_case('elbow.cas.h5')
196
- solver_session.tui.define.models.unsteady_2nd_order("yes")
197
- solver_session.tui.solve.initialize.initialize_flow()
198
- solver_session.tui.solve.dual_time_iterate(2, 3)
202
+ import ansys.fluent.core as pyfluent
203
+
204
+ solver_session = pyfluent.launch_fluent()
205
+
206
+ For more information on using the ``solver_session`` interface, see the
207
+ `PyFluent documentation <https://fluent.docs.pyansys.com/version/stable/>`_.
199
208
 
200
- You can also install and use these PyFluent libraries:
209
+ For postprocessing and visualization, you can also install:
201
210
 
202
- - `PyFluent Parametric <https://parametric.fluent.docs.pyansys.com/>`_, which provides
203
- access to Fluent's parametric workflows.
204
211
  - `PyFluent Visualization <https://visualization.fluent.docs.pyansys.com/>`_, which
205
- provides postprocessing and visualization capabilities using the `pyvista <https://docs.pyvista.org/>`_
212
+ enables analysis and plotting through the `pyvista <https://docs.pyvista.org/>`_
206
213
  and `matplotlib <https://matplotlib.org/>`_ packages.
207
214
 
208
215
  License and acknowledgments