ansys-fluent-core 0.33.0__py3-none-any.whl → 0.34.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.
- ansys/fluent/core/__init__.py +3 -3
- ansys/fluent/core/codegen/builtin_settingsgen.py +25 -19
- ansys/fluent/core/codegen/settingsgen.py +17 -5
- ansys/fluent/core/codegen/tuigen.py +2 -1
- ansys/fluent/core/docker/docker_compose.py +4 -1
- ansys/fluent/core/docker/utils.py +35 -0
- ansys/fluent/core/exceptions.py +13 -1
- ansys/fluent/core/field_data_interfaces.py +239 -38
- ansys/fluent/core/file_session.py +139 -59
- ansys/fluent/core/fluent_connection.py +23 -16
- ansys/fluent/core/generated/api_tree/api_objects.json +1 -1
- ansys/fluent/core/generated/datamodel_231/flicing.py +30 -30
- ansys/fluent/core/generated/datamodel_231/meshing.py +171 -171
- ansys/fluent/core/generated/datamodel_232/flicing.py +35 -35
- ansys/fluent/core/generated/datamodel_232/meshing.py +223 -223
- ansys/fluent/core/generated/datamodel_241/flicing.py +35 -35
- ansys/fluent/core/generated/datamodel_241/meshing.py +264 -264
- ansys/fluent/core/generated/datamodel_242/flicing.py +30 -30
- ansys/fluent/core/generated/datamodel_242/meshing.py +369 -369
- ansys/fluent/core/generated/datamodel_251/flicing.py +35 -35
- ansys/fluent/core/generated/datamodel_251/meshing.py +331 -331
- ansys/fluent/core/generated/datamodel_251/part_management.py +3 -3
- ansys/fluent/core/generated/datamodel_252/flicing.py +50 -50
- ansys/fluent/core/generated/datamodel_252/meshing.py +398 -398
- ansys/fluent/core/generated/datamodel_252/part_management.py +5 -5
- ansys/fluent/core/generated/datamodel_261/flicing.py +40 -40
- ansys/fluent/core/generated/datamodel_261/meshing.py +416 -397
- ansys/fluent/core/generated/datamodel_261/part_management.py +10 -10
- ansys/fluent/core/generated/datamodel_261/preferences.py +7 -0
- ansys/fluent/core/generated/fluent_version_261.py +3 -3
- ansys/fluent/core/generated/meshing/tui_261.py +1186 -1180
- 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 +56 -22
- ansys/fluent/core/generated/solver/settings_builtin.pyi +22 -0
- ansys/fluent/core/generated/solver/tui_261.py +2445 -2281
- ansys/fluent/core/launcher/container_launcher.py +6 -2
- ansys/fluent/core/launcher/error_handler.py +1 -1
- ansys/fluent/core/launcher/fluent_container.py +53 -10
- ansys/fluent/core/launcher/launcher.py +3 -0
- ansys/fluent/core/launcher/watchdog.py +6 -6
- ansys/fluent/core/launcher/watchdog_exec +1 -1
- ansys/fluent/core/pyfluent_warnings.py +7 -1
- ansys/fluent/core/report.py +2 -0
- ansys/fluent/core/search.py +11 -3
- ansys/fluent/core/services/__init__.py +2 -2
- ansys/fluent/core/services/app_utilities.py +39 -0
- ansys/fluent/core/services/deprecated_field_data.py +4 -4
- ansys/fluent/core/services/field_data.py +158 -41
- ansys/fluent/core/services/reduction.py +16 -5
- ansys/fluent/core/services/settings.py +1 -0
- ansys/fluent/core/session.py +16 -1
- ansys/fluent/core/session_pure_meshing.py +5 -5
- ansys/fluent/core/session_pure_meshing.pyi +1 -0
- ansys/fluent/core/session_solver.py +33 -8
- ansys/fluent/core/session_solver.pyi +1 -0
- ansys/fluent/core/solver/error_message.py +2 -2
- ansys/fluent/core/solver/flobject.py +187 -120
- ansys/fluent/core/solver/function/reduction.py +37 -9
- ansys/fluent/core/solver/settings_builtin_data.py +5 -3
- ansys/fluent/core/utils/fluent_version.py +1 -3
- ansys/fluent/core/utils/networking.py +18 -8
- {ansys_fluent_core-0.33.0.dist-info → ansys_fluent_core-0.34.0.dist-info}/METADATA +10 -11
- {ansys_fluent_core-0.33.0.dist-info → ansys_fluent_core-0.34.0.dist-info}/RECORD +78 -77
- {ansys_fluent_core-0.33.0.dist-info → ansys_fluent_core-0.34.0.dist-info}/WHEEL +1 -1
- {ansys_fluent_core-0.33.0.dist-info/licenses → ansys_fluent_core-0.34.0.dist-info}/LICENSE +0 -0
|
@@ -44,6 +44,7 @@ import collections
|
|
|
44
44
|
from contextlib import contextmanager, nullcontext
|
|
45
45
|
import fnmatch
|
|
46
46
|
import hashlib
|
|
47
|
+
import inspect
|
|
47
48
|
import keyword
|
|
48
49
|
import logging
|
|
49
50
|
import os
|
|
@@ -54,6 +55,7 @@ import sys
|
|
|
54
55
|
import types
|
|
55
56
|
from typing import (
|
|
56
57
|
Any,
|
|
58
|
+
Callable,
|
|
57
59
|
Dict,
|
|
58
60
|
ForwardRef,
|
|
59
61
|
Generic,
|
|
@@ -88,6 +90,14 @@ from .settings_external import expand_api_file_argument
|
|
|
88
90
|
settings_logger = logging.getLogger("pyfluent.settings_api")
|
|
89
91
|
|
|
90
92
|
|
|
93
|
+
_static_class_attributes = [
|
|
94
|
+
"_version",
|
|
95
|
+
"_deprecated_version",
|
|
96
|
+
"_python_name",
|
|
97
|
+
"fluent_name",
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
|
|
91
101
|
class InactiveObjectError(RuntimeError):
|
|
92
102
|
"""Inactive object access."""
|
|
93
103
|
|
|
@@ -178,7 +188,7 @@ _ttable = str.maketrans(string.punctuation, "_" * len(string.punctuation), "?'")
|
|
|
178
188
|
def to_python_name(fluent_name: str) -> str:
|
|
179
189
|
"""Convert a scheme string to a Python variable name.
|
|
180
190
|
|
|
181
|
-
This function replaces symbols with _.
|
|
191
|
+
This function replaces symbols with _. ``'`` and ``?`` symbols are
|
|
182
192
|
ignored.
|
|
183
193
|
"""
|
|
184
194
|
if not fluent_name:
|
|
@@ -189,6 +199,22 @@ def to_python_name(fluent_name: str) -> str:
|
|
|
189
199
|
return name
|
|
190
200
|
|
|
191
201
|
|
|
202
|
+
def to_constant_name(fluent_name: str) -> str:
|
|
203
|
+
"""Convert a scheme string to a Python constant name.
|
|
204
|
+
|
|
205
|
+
This function replaces symbols and spaces with _ and converts the name to uppercase.
|
|
206
|
+
``'`` and ``?`` symbols are ignored.
|
|
207
|
+
"""
|
|
208
|
+
fluent_name = fluent_name.replace(" ", "_")
|
|
209
|
+
name = fluent_name.translate(_ttable).upper()
|
|
210
|
+
if not name:
|
|
211
|
+
return "EMPTY_STRING"
|
|
212
|
+
if name[0].isdigit():
|
|
213
|
+
# If the first character is a digit, prepend "CASE_"
|
|
214
|
+
name = "CASE_" + name
|
|
215
|
+
return name
|
|
216
|
+
|
|
217
|
+
|
|
192
218
|
_to_field_name_str = naming_strategy().to_string
|
|
193
219
|
|
|
194
220
|
|
|
@@ -236,9 +262,8 @@ def _is_deprecated(obj) -> bool | None:
|
|
|
236
262
|
deprecated_version = (
|
|
237
263
|
deprecated_version.get("deprecated-version") if deprecated_version else None
|
|
238
264
|
)
|
|
239
|
-
return deprecated_version and (
|
|
240
|
-
|
|
241
|
-
or FluentVersion(obj._version) >= FluentVersion(deprecated_version)
|
|
265
|
+
return deprecated_version and FluentVersion(obj._version) >= FluentVersion(
|
|
266
|
+
deprecated_version
|
|
242
267
|
)
|
|
243
268
|
|
|
244
269
|
|
|
@@ -496,6 +521,39 @@ class Base:
|
|
|
496
521
|
return False
|
|
497
522
|
return self.flproxy == other.flproxy and self.path == other.path
|
|
498
523
|
|
|
524
|
+
def get_completer_info(self, prefix="", excluded=None) -> List[List[str]]:
|
|
525
|
+
"""Get completer info of all children.
|
|
526
|
+
|
|
527
|
+
Returns
|
|
528
|
+
-------
|
|
529
|
+
List[List[str]]
|
|
530
|
+
Name, type and docstring of all children.
|
|
531
|
+
"""
|
|
532
|
+
excluded = excluded or []
|
|
533
|
+
ret = []
|
|
534
|
+
for k, v in inspect.getmembers(self):
|
|
535
|
+
if not k.startswith("_") and k not in excluded and k.startswith(prefix):
|
|
536
|
+
if isinstance(v, Base):
|
|
537
|
+
if not _is_deprecated(v):
|
|
538
|
+
ret.append(
|
|
539
|
+
[
|
|
540
|
+
k,
|
|
541
|
+
_get_type_for_completer_info(v.__class__),
|
|
542
|
+
v.__doc__,
|
|
543
|
+
]
|
|
544
|
+
)
|
|
545
|
+
elif inspect.ismethod(v):
|
|
546
|
+
ret.append(
|
|
547
|
+
[
|
|
548
|
+
k,
|
|
549
|
+
"Method",
|
|
550
|
+
v.__doc__ or "",
|
|
551
|
+
]
|
|
552
|
+
)
|
|
553
|
+
else:
|
|
554
|
+
ret.append([k, "Data", ""])
|
|
555
|
+
return ret
|
|
556
|
+
|
|
499
557
|
|
|
500
558
|
StateT = TypeVar("StateT")
|
|
501
559
|
|
|
@@ -946,20 +1004,6 @@ class BooleanList(SettingsBase[BoolListType], Property):
|
|
|
946
1004
|
_state_type = BoolListType
|
|
947
1005
|
|
|
948
1006
|
|
|
949
|
-
def _command_query_name_filter(
|
|
950
|
-
parent, list_attr: str, prefix: str, excluded: List[str]
|
|
951
|
-
) -> List:
|
|
952
|
-
"""Auto completer info of commands and queries."""
|
|
953
|
-
ret = []
|
|
954
|
-
names = getattr(parent, list_attr)
|
|
955
|
-
for name in names:
|
|
956
|
-
if name not in excluded and name.startswith(prefix):
|
|
957
|
-
child = getattr(parent, name)
|
|
958
|
-
if child.is_active() and not _is_deprecated(child):
|
|
959
|
-
ret.append([name, child.__class__.__bases__[0].__name__, child.__doc__])
|
|
960
|
-
return ret
|
|
961
|
-
|
|
962
|
-
|
|
963
1007
|
def _get_type_for_completer_info(cls) -> str:
|
|
964
1008
|
if issubclass(cls, (FileName, _InputFile)):
|
|
965
1009
|
return "InputFilename"
|
|
@@ -1097,41 +1141,14 @@ class Group(SettingsBase[DictStateType]):
|
|
|
1097
1141
|
[
|
|
1098
1142
|
child
|
|
1099
1143
|
for child in self.child_names + self.command_names + self.query_names
|
|
1100
|
-
if getattr(self, child)
|
|
1101
|
-
and _is_deprecated(getattr(self, child))
|
|
1144
|
+
if _is_deprecated(getattr(self, child))
|
|
1102
1145
|
]
|
|
1103
1146
|
)
|
|
1104
1147
|
|
|
1105
|
-
def get_completer_info(self, prefix="", excluded=None) -> List[List[str]]:
|
|
1106
|
-
"""Get completer info of all children.
|
|
1107
|
-
|
|
1108
|
-
Returns
|
|
1109
|
-
-------
|
|
1110
|
-
List[List[str]]
|
|
1111
|
-
Name, type and docstring of all children.
|
|
1112
|
-
"""
|
|
1113
|
-
excluded = excluded or []
|
|
1114
|
-
ret = []
|
|
1115
|
-
for child_name in self.child_names:
|
|
1116
|
-
if child_name not in excluded and child_name.startswith(prefix):
|
|
1117
|
-
child = getattr(self, child_name)
|
|
1118
|
-
if child.is_active() and not _is_deprecated(child):
|
|
1119
|
-
ret.append(
|
|
1120
|
-
[
|
|
1121
|
-
child_name,
|
|
1122
|
-
_get_type_for_completer_info(child.__class__),
|
|
1123
|
-
child.__doc__,
|
|
1124
|
-
]
|
|
1125
|
-
)
|
|
1126
|
-
command_info = _command_query_name_filter(
|
|
1127
|
-
self, "command_names", prefix, excluded
|
|
1128
|
-
)
|
|
1129
|
-
query_info = _command_query_name_filter(self, "query_names", prefix, excluded)
|
|
1130
|
-
for items in [command_info, query_info]:
|
|
1131
|
-
ret.extend(items)
|
|
1132
|
-
return ret
|
|
1133
|
-
|
|
1134
1148
|
def __getattribute__(self, name):
|
|
1149
|
+
# Avoiding server queries for static attributes
|
|
1150
|
+
if name in _static_class_attributes:
|
|
1151
|
+
return super().__getattribute__(name)
|
|
1135
1152
|
if (
|
|
1136
1153
|
name in super().__getattribute__("child_names")
|
|
1137
1154
|
and self.is_active() is False
|
|
@@ -1153,9 +1170,7 @@ class Group(SettingsBase[DictStateType]):
|
|
|
1153
1170
|
error_msg = allowed_name_error_message(
|
|
1154
1171
|
trial_name=name,
|
|
1155
1172
|
message=ex.args[0],
|
|
1156
|
-
allowed_values=sorted(
|
|
1157
|
-
set(self.get_active_child_names() + self.command_names)
|
|
1158
|
-
),
|
|
1173
|
+
allowed_values=sorted(set(self.child_names + self.command_names)),
|
|
1159
1174
|
)
|
|
1160
1175
|
ex.args = (error_msg,)
|
|
1161
1176
|
raise
|
|
@@ -1402,24 +1417,6 @@ class NamedObject(SettingsBase[DictStateType], Generic[ChildTypeT]):
|
|
|
1402
1417
|
obj_names_list = obj_names if isinstance(obj_names, list) else list(obj_names)
|
|
1403
1418
|
return obj_names_list
|
|
1404
1419
|
|
|
1405
|
-
def get_completer_info(self, prefix="", excluded=None) -> List[List[str]]:
|
|
1406
|
-
"""Get completer info of all children.
|
|
1407
|
-
|
|
1408
|
-
Returns
|
|
1409
|
-
-------
|
|
1410
|
-
List[List[str]]
|
|
1411
|
-
Name, type and docstring of all children.
|
|
1412
|
-
"""
|
|
1413
|
-
excluded = excluded or []
|
|
1414
|
-
ret = []
|
|
1415
|
-
command_info = _command_query_name_filter(
|
|
1416
|
-
self, "command_names", prefix, excluded
|
|
1417
|
-
)
|
|
1418
|
-
query_info = _command_query_name_filter(self, "query_names", prefix, excluded)
|
|
1419
|
-
for items in [command_info, query_info]:
|
|
1420
|
-
ret.extend(items)
|
|
1421
|
-
return ret
|
|
1422
|
-
|
|
1423
1420
|
def __getitem__(self, name: str) -> ChildTypeT:
|
|
1424
1421
|
if name not in self.get_object_names():
|
|
1425
1422
|
if self.flproxy.has_wildcard(name):
|
|
@@ -1475,7 +1472,54 @@ class NamedObject(SettingsBase[DictStateType], Generic[ChildTypeT]):
|
|
|
1475
1472
|
)
|
|
1476
1473
|
return alias_obj
|
|
1477
1474
|
else:
|
|
1478
|
-
|
|
1475
|
+
try:
|
|
1476
|
+
return getattr(super(), name)
|
|
1477
|
+
except AttributeError as ex:
|
|
1478
|
+
raise AttributeError(
|
|
1479
|
+
f"'{self.__class__.__name__}' has no attribute '{name}'"
|
|
1480
|
+
) from ex
|
|
1481
|
+
|
|
1482
|
+
def __add__(self, other):
|
|
1483
|
+
if not isinstance(other, NamedObject):
|
|
1484
|
+
raise TypeError(
|
|
1485
|
+
f"Can only add NamedObject to NamedObject, not {type(other).__name__}"
|
|
1486
|
+
)
|
|
1487
|
+
return CombinedNamedObject([self, other])
|
|
1488
|
+
|
|
1489
|
+
|
|
1490
|
+
class CombinedNamedObject:
|
|
1491
|
+
"""A ``CombinedNamedObject`` contains the concatenated named-objects."""
|
|
1492
|
+
|
|
1493
|
+
def __init__(self, objects: list[NamedObject]):
|
|
1494
|
+
"""__init__ of CombinedNamedObject."""
|
|
1495
|
+
self.objects = []
|
|
1496
|
+
self._items = []
|
|
1497
|
+
for obj in objects:
|
|
1498
|
+
if isinstance(obj, CombinedNamedObject):
|
|
1499
|
+
self.objects.extend(obj.objects)
|
|
1500
|
+
else:
|
|
1501
|
+
self.objects.append(obj)
|
|
1502
|
+
for obj in self.objects:
|
|
1503
|
+
self._items.extend(obj.items())
|
|
1504
|
+
|
|
1505
|
+
def items(self):
|
|
1506
|
+
"""Return items like a dictionary."""
|
|
1507
|
+
return self._items
|
|
1508
|
+
|
|
1509
|
+
def __iter__(self):
|
|
1510
|
+
for obj in self.objects:
|
|
1511
|
+
yield from obj
|
|
1512
|
+
|
|
1513
|
+
def __add__(self, other):
|
|
1514
|
+
if not isinstance(other, NamedObject):
|
|
1515
|
+
raise TypeError(f"Cannot add {type(self)} to NamedObject")
|
|
1516
|
+
return CombinedNamedObject(self.objects + [other])
|
|
1517
|
+
|
|
1518
|
+
def __call__(self):
|
|
1519
|
+
temp_dict = {}
|
|
1520
|
+
for obj in self.objects:
|
|
1521
|
+
temp_dict.update(obj())
|
|
1522
|
+
return temp_dict
|
|
1479
1523
|
|
|
1480
1524
|
|
|
1481
1525
|
def _rename(obj: NamedObject | _Alias, new: str, old: str):
|
|
@@ -1613,11 +1657,16 @@ def _get_new_keywords(obj, *args, **kwds):
|
|
|
1613
1657
|
newkwds[argName] = arg
|
|
1614
1658
|
if kwds:
|
|
1615
1659
|
# Convert deprecated keywords through aliases
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1660
|
+
if FluentVersion(obj._version) >= FluentVersion.v252:
|
|
1661
|
+
argument_aliases = {k: v[0] for k, v in obj._child_aliases.items()}
|
|
1662
|
+
else:
|
|
1663
|
+
# Arguments-aliases was not statically available before v252.
|
|
1664
|
+
argument_aliases_scm = obj.get_attr("arguments-aliases") or {}
|
|
1665
|
+
argument_aliases = {}
|
|
1666
|
+
for k, v in argument_aliases_scm.items():
|
|
1667
|
+
argument_aliases[to_python_name(k)] = to_python_name(
|
|
1668
|
+
v.removeprefix("'")
|
|
1669
|
+
)
|
|
1621
1670
|
for k, v in kwds.items():
|
|
1622
1671
|
alias = argument_aliases.get(k)
|
|
1623
1672
|
if alias:
|
|
@@ -1657,34 +1706,10 @@ class Action(Base):
|
|
|
1657
1706
|
[
|
|
1658
1707
|
child
|
|
1659
1708
|
for child in self.argument_names
|
|
1660
|
-
if getattr(self, child)
|
|
1661
|
-
and _is_deprecated(getattr(self, child))
|
|
1709
|
+
if _is_deprecated(getattr(self, child))
|
|
1662
1710
|
]
|
|
1663
1711
|
)
|
|
1664
1712
|
|
|
1665
|
-
def get_completer_info(self, prefix="", excluded=None) -> List[List[str]]:
|
|
1666
|
-
"""Get completer info of all arguments.
|
|
1667
|
-
|
|
1668
|
-
Returns
|
|
1669
|
-
-------
|
|
1670
|
-
List[List[str]]
|
|
1671
|
-
Name, type and docstring of all arguments.
|
|
1672
|
-
"""
|
|
1673
|
-
excluded = excluded or []
|
|
1674
|
-
ret = []
|
|
1675
|
-
for argument_name in self.argument_names:
|
|
1676
|
-
if argument_name not in excluded and argument_name.startswith(prefix):
|
|
1677
|
-
argument = getattr(self, argument_name)
|
|
1678
|
-
if argument.is_active() and not _is_deprecated(argument):
|
|
1679
|
-
ret.append(
|
|
1680
|
-
[
|
|
1681
|
-
argument_name,
|
|
1682
|
-
_get_type_for_completer_info(argument.__class__),
|
|
1683
|
-
argument.__doc__,
|
|
1684
|
-
]
|
|
1685
|
-
)
|
|
1686
|
-
return ret
|
|
1687
|
-
|
|
1688
1713
|
def __getattr__(self, name: str):
|
|
1689
1714
|
alias = self._child_aliases.get(name)
|
|
1690
1715
|
if alias:
|
|
@@ -1721,12 +1746,16 @@ class BaseCommand(Action):
|
|
|
1721
1746
|
print("Please enter 'y[es]' or 'n[o]'.")
|
|
1722
1747
|
with self._while_executing_command():
|
|
1723
1748
|
ret = self.flproxy.execute_cmd(self._parent.path, self.obj_name, **kwds)
|
|
1724
|
-
if
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1749
|
+
if (
|
|
1750
|
+
os.getenv("PYFLUENT_NO_FIX_PARAMETER_LIST_RETURN") != "1"
|
|
1751
|
+
and FluentVersion(self._version) <= FluentVersion.v252
|
|
1752
|
+
and self.path
|
|
1753
|
+
in [
|
|
1754
|
+
"parameters/input-parameters/list",
|
|
1755
|
+
"parameters/output-parameters/list",
|
|
1756
|
+
]
|
|
1757
|
+
):
|
|
1758
|
+
ret = _fix_parameter_list_return(ret)
|
|
1730
1759
|
return ret
|
|
1731
1760
|
|
|
1732
1761
|
def execute_command(self, *args, **kwds):
|
|
@@ -1764,13 +1793,6 @@ class BaseCommand(Action):
|
|
|
1764
1793
|
assert_type(ret, base_t._state_type)
|
|
1765
1794
|
return ret
|
|
1766
1795
|
|
|
1767
|
-
def __call__(self, *args, **kwds):
|
|
1768
|
-
try:
|
|
1769
|
-
return self.execute_command(*args, **kwds)
|
|
1770
|
-
except KeyboardInterrupt:
|
|
1771
|
-
self._root._on_interrupt(self)
|
|
1772
|
-
raise KeyboardInterrupt
|
|
1773
|
-
|
|
1774
1796
|
|
|
1775
1797
|
# TODO: Remove this after parameter list() method is fixed from Fluent side
|
|
1776
1798
|
def _fix_parameter_list_return(val):
|
|
@@ -1807,6 +1829,8 @@ class Command(BaseCommand):
|
|
|
1807
1829
|
|
|
1808
1830
|
def __call__(self, **kwds):
|
|
1809
1831
|
"""Call a command with the specified keyword arguments."""
|
|
1832
|
+
if not self.is_active():
|
|
1833
|
+
raise InactiveObjectError(self.python_path)
|
|
1810
1834
|
try:
|
|
1811
1835
|
return self.execute_command(**kwds)
|
|
1812
1836
|
except KeyboardInterrupt:
|
|
@@ -1819,6 +1843,8 @@ class CommandWithPositionalArgs(BaseCommand):
|
|
|
1819
1843
|
|
|
1820
1844
|
def __call__(self, *args, **kwds):
|
|
1821
1845
|
"""Call a command with the specified positional and keyword arguments."""
|
|
1846
|
+
if not self.is_active():
|
|
1847
|
+
raise InactiveObjectError(self.python_path)
|
|
1822
1848
|
try:
|
|
1823
1849
|
return self.execute_command(*args, **kwds)
|
|
1824
1850
|
except KeyboardInterrupt:
|
|
@@ -1831,6 +1857,8 @@ class Query(Action):
|
|
|
1831
1857
|
|
|
1832
1858
|
def __call__(self, **kwds):
|
|
1833
1859
|
"""Call a query with the specified keyword arguments."""
|
|
1860
|
+
if not self.is_active():
|
|
1861
|
+
raise InactiveObjectError(self.python_path)
|
|
1834
1862
|
kwds = _get_new_keywords(self, **kwds)
|
|
1835
1863
|
scmKwds = {}
|
|
1836
1864
|
for arg, value in kwds.items():
|
|
@@ -2027,6 +2055,33 @@ class AllowedValuesMixin:
|
|
|
2027
2055
|
return []
|
|
2028
2056
|
|
|
2029
2057
|
|
|
2058
|
+
class _MaybeActiveString(str):
|
|
2059
|
+
"""A string class with an is_active() method."""
|
|
2060
|
+
|
|
2061
|
+
def __new__(cls, value, is_active: Callable[[], bool]):
|
|
2062
|
+
return super().__new__(cls, value)
|
|
2063
|
+
|
|
2064
|
+
def __init__(self, value, is_active: Callable[[], bool]):
|
|
2065
|
+
super().__init__()
|
|
2066
|
+
self.is_active = is_active
|
|
2067
|
+
|
|
2068
|
+
|
|
2069
|
+
class _FlStringConstant:
|
|
2070
|
+
"""A descriptor class to hold a constant string value."""
|
|
2071
|
+
|
|
2072
|
+
def __init__(self, value):
|
|
2073
|
+
self._value = value
|
|
2074
|
+
|
|
2075
|
+
def __get__(self, instance, owner):
|
|
2076
|
+
def is_active():
|
|
2077
|
+
return self._value in instance.allowed_values()
|
|
2078
|
+
|
|
2079
|
+
return _MaybeActiveString(self._value, is_active=is_active)
|
|
2080
|
+
|
|
2081
|
+
def __set__(self, instance, value):
|
|
2082
|
+
raise AttributeError("Cannot set a constant value.")
|
|
2083
|
+
|
|
2084
|
+
|
|
2030
2085
|
_bases_by_class = {}
|
|
2031
2086
|
|
|
2032
2087
|
|
|
@@ -2111,8 +2166,11 @@ def get_cls(name, info, parent=None, version=None, parent_taboo=None):
|
|
|
2111
2166
|
dct["_child_classes"] = {}
|
|
2112
2167
|
cls = type(pname, bases, dct)
|
|
2113
2168
|
|
|
2114
|
-
deprecated_version = info.get("deprecated_version",
|
|
2115
|
-
|
|
2169
|
+
deprecated_version = info.get("deprecated_version", None)
|
|
2170
|
+
if deprecated_version and float(deprecated_version) >= 22.2:
|
|
2171
|
+
cls._deprecated_version = deprecated_version
|
|
2172
|
+
else:
|
|
2173
|
+
cls._deprecated_version = ""
|
|
2116
2174
|
|
|
2117
2175
|
taboo = set(dir(cls))
|
|
2118
2176
|
taboo |= set(
|
|
@@ -2156,7 +2214,6 @@ def get_cls(name, info, parent=None, version=None, parent_taboo=None):
|
|
|
2156
2214
|
commands = info.get("commands")
|
|
2157
2215
|
if commands:
|
|
2158
2216
|
commands.pop("exit", None)
|
|
2159
|
-
commands.pop("switch-to-meshing-mode", None)
|
|
2160
2217
|
if commands and not user_creatable:
|
|
2161
2218
|
commands.pop("create", None)
|
|
2162
2219
|
if commands:
|
|
@@ -2195,14 +2252,14 @@ def get_cls(name, info, parent=None, version=None, parent_taboo=None):
|
|
|
2195
2252
|
child_aliases = info.get("child-aliases") or info.get("child_aliases", {})
|
|
2196
2253
|
command_aliases = info.get("command-aliases") or info.get("command_aliases", {})
|
|
2197
2254
|
query_aliases = info.get("query-aliases") or info.get("query_aliases", {})
|
|
2198
|
-
|
|
2255
|
+
arguments_aliases = info.get("arguments-aliases") or info.get(
|
|
2199
2256
|
"arguments_aliases", {}
|
|
2200
2257
|
)
|
|
2201
|
-
if child_aliases or command_aliases or query_aliases or
|
|
2258
|
+
if child_aliases or command_aliases or query_aliases or arguments_aliases:
|
|
2202
2259
|
cls._child_aliases = {}
|
|
2203
2260
|
# No need to differentiate in the Python implementation
|
|
2204
2261
|
for k, v in (
|
|
2205
|
-
child_aliases | command_aliases | query_aliases |
|
|
2262
|
+
child_aliases | command_aliases | query_aliases | arguments_aliases
|
|
2206
2263
|
).items():
|
|
2207
2264
|
# Storing the original name as we don't have any other way
|
|
2208
2265
|
# to recover it at runtime.
|
|
@@ -2213,6 +2270,16 @@ def get_cls(name, info, parent=None, version=None, parent_taboo=None):
|
|
|
2213
2270
|
k,
|
|
2214
2271
|
)
|
|
2215
2272
|
|
|
2273
|
+
allowed_values = info.get("allowed-values") or info.get("allowed_values", [])
|
|
2274
|
+
if allowed_values:
|
|
2275
|
+
for allowed_value in allowed_values:
|
|
2276
|
+
setattr(
|
|
2277
|
+
cls,
|
|
2278
|
+
to_constant_name(allowed_value),
|
|
2279
|
+
_FlStringConstant(allowed_value),
|
|
2280
|
+
)
|
|
2281
|
+
cls._allowed_values = allowed_values
|
|
2282
|
+
|
|
2216
2283
|
except Exception:
|
|
2217
2284
|
print(
|
|
2218
2285
|
f"Unable to construct class for '{name}' of "
|
|
@@ -74,16 +74,35 @@ Examples
|
|
|
74
74
|
>>> vsquared.definition = "VelocityMagnitude ** 2"
|
|
75
75
|
>>> reduction.minimum(
|
|
76
76
|
... expr = vsquared,
|
|
77
|
-
... locations =
|
|
78
|
-
...
|
|
79
|
-
...
|
|
80
|
-
... ])
|
|
77
|
+
... locations = solver1.setup.boundary_conditions.pressure_outlet
|
|
78
|
+
... + solver2.setup.boundary_conditions.pressure_outlet
|
|
79
|
+
... )
|
|
81
80
|
19.28151
|
|
82
81
|
"""
|
|
82
|
+
from collections.abc import Iterable
|
|
83
|
+
from enum import Enum
|
|
83
84
|
|
|
84
85
|
import numpy as np
|
|
85
86
|
from numpy import array
|
|
86
87
|
|
|
88
|
+
from ansys.fluent.core.exceptions import DisallowedValuesError
|
|
89
|
+
from ansys.fluent.core.variable_strategies import (
|
|
90
|
+
FluentExprNamingStrategy as naming_strategy,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class Weight(Enum):
|
|
95
|
+
"""Weight for sum."""
|
|
96
|
+
|
|
97
|
+
AREA = "Area"
|
|
98
|
+
VOLUME = "Volume"
|
|
99
|
+
MASS = "Mass"
|
|
100
|
+
MASS_FLOW_RATE = "MassFlowRate"
|
|
101
|
+
ABS_MASS_FLOW_RATE = "AbsMassFlowRate"
|
|
102
|
+
|
|
103
|
+
def __str__(self):
|
|
104
|
+
return self.value
|
|
105
|
+
|
|
87
106
|
|
|
88
107
|
class BadReductionRequest(Exception):
|
|
89
108
|
"""Raised on an attempt to make a bad reduction request."""
|
|
@@ -117,7 +136,12 @@ def _locn_name_and_obj(locn, locns):
|
|
|
117
136
|
def _locn_names_and_objs(locns):
|
|
118
137
|
if _is_iterable(locns):
|
|
119
138
|
names_and_objs = []
|
|
139
|
+
if locns.__class__.__name__ == "CombinedNamedObject":
|
|
140
|
+
return locns.items()
|
|
141
|
+
|
|
120
142
|
for locn in locns:
|
|
143
|
+
if isinstance(locn, Iterable) and not isinstance(locn, (str, bytes)):
|
|
144
|
+
raise DisallowedValuesError("location", locn, list(locn))
|
|
121
145
|
name_and_obj = _locn_name_and_obj(locn, locns)
|
|
122
146
|
if _is_iterable(name_and_obj):
|
|
123
147
|
if isinstance(name_and_obj[0], str):
|
|
@@ -187,7 +211,7 @@ def _eval_reduction(
|
|
|
187
211
|
weight = "Weight=" + str(weight)
|
|
188
212
|
locations = str(locations) + ", " + weight
|
|
189
213
|
|
|
190
|
-
expr_str = _expr_to_expr_str(expr)
|
|
214
|
+
expr_str = _expr_to_expr_str(naming_strategy().to_string(expr))
|
|
191
215
|
if condition:
|
|
192
216
|
expr_str = expr_str + ", " + condition
|
|
193
217
|
return _eval_expr(
|
|
@@ -291,6 +315,10 @@ def _limit(limit, expr, locations, ctxt):
|
|
|
291
315
|
return limit_val
|
|
292
316
|
|
|
293
317
|
|
|
318
|
+
# Weight for sum
|
|
319
|
+
weight = Weight
|
|
320
|
+
|
|
321
|
+
|
|
294
322
|
def area_average(expression, locations, ctxt=None):
|
|
295
323
|
"""Compute the area averaged value of the specified expression over the specified
|
|
296
324
|
locations.
|
|
@@ -579,14 +607,14 @@ def mass_flow(locations, ctxt=None):
|
|
|
579
607
|
return _extent("MassFlow", locations, ctxt)
|
|
580
608
|
|
|
581
609
|
|
|
582
|
-
def sum(expression, locations, weight, ctxt=None):
|
|
610
|
+
def sum(expression, locations, weight: str | Weight, ctxt=None):
|
|
583
611
|
"""Compute the sum of the specified expression over the specified locations.
|
|
584
612
|
|
|
585
613
|
Parameters
|
|
586
614
|
----------
|
|
587
615
|
expression : Any
|
|
588
616
|
locations : Any
|
|
589
|
-
weight: str
|
|
617
|
+
weight: str | Weight
|
|
590
618
|
ctxt : Any, optional
|
|
591
619
|
Returns
|
|
592
620
|
-------
|
|
@@ -595,7 +623,7 @@ def sum(expression, locations, weight, ctxt=None):
|
|
|
595
623
|
return _extent_expression("Sum", "Sum", expression, locations, ctxt, weight=weight)
|
|
596
624
|
|
|
597
625
|
|
|
598
|
-
def sum_if(expression, condition, locations, weight, ctxt=None):
|
|
626
|
+
def sum_if(expression, condition, locations, weight: str | Weight, ctxt=None):
|
|
599
627
|
"""Compute the sum of the specified expression over the specified locations if a
|
|
600
628
|
condition is satisfied.
|
|
601
629
|
|
|
@@ -604,7 +632,7 @@ def sum_if(expression, condition, locations, weight, ctxt=None):
|
|
|
604
632
|
expression : Any
|
|
605
633
|
condition: str
|
|
606
634
|
locations : Any
|
|
607
|
-
weight: str
|
|
635
|
+
weight: str | Weight
|
|
608
636
|
ctxt : Any, optional
|
|
609
637
|
Returns
|
|
610
638
|
-------
|
|
@@ -729,23 +729,25 @@ DATA = {
|
|
|
729
729
|
"ReadData": ("Command", "file.read_data"),
|
|
730
730
|
"ReadCaseData": ("Command", "file.read_case_data"),
|
|
731
731
|
"WriteCase": (
|
|
732
|
-
"
|
|
732
|
+
"Command",
|
|
733
733
|
{
|
|
734
734
|
since(FluentVersion.v241): "file.write_case",
|
|
735
735
|
},
|
|
736
736
|
),
|
|
737
737
|
"WriteData": (
|
|
738
|
-
"
|
|
738
|
+
"Command",
|
|
739
739
|
{
|
|
740
740
|
since(FluentVersion.v241): "file.write_data",
|
|
741
741
|
},
|
|
742
742
|
),
|
|
743
743
|
"WriteCaseData": (
|
|
744
|
-
"
|
|
744
|
+
"Command",
|
|
745
745
|
{
|
|
746
746
|
since(FluentVersion.v241): "file.write_case_data",
|
|
747
747
|
},
|
|
748
748
|
),
|
|
749
749
|
"Initialize": ("Command", "solution.initialization.initialize"),
|
|
750
750
|
"Calculate": ("Command", "solution.run_calculation.calculate"),
|
|
751
|
+
"Iterate": ("Command", "solution.run_calculation.iterate"),
|
|
752
|
+
"DualTimeIterate": ("Command", "solution.run_calculation.dual_time_iterate"),
|
|
751
753
|
}
|
|
@@ -201,9 +201,7 @@ class FluentVersion(Enum):
|
|
|
201
201
|
|
|
202
202
|
def __str__(self) -> str:
|
|
203
203
|
"""String output for the Fluent version."""
|
|
204
|
-
return (
|
|
205
|
-
f"Fluent version 20{self.value.split('.')[0]} R{self.value.split('.')[1]}"
|
|
206
|
-
)
|
|
204
|
+
return f"Ansys Fluent 20{self.value.split('.')[0]} R{self.value.split('.')[1]}"
|
|
207
205
|
|
|
208
206
|
|
|
209
207
|
class FluentVersionSet(Set[FluentVersion]):
|
|
@@ -81,14 +81,24 @@ def find_remoting_ip() -> str:
|
|
|
81
81
|
"""
|
|
82
82
|
from ansys.fluent.core import INFER_REMOTING_IP_TIMEOUT_PER_IP
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
all_ips = [
|
|
85
|
+
addrinfo[-1][0]
|
|
86
|
+
for addrinfo in socket.getaddrinfo(
|
|
87
|
+
"localhost",
|
|
88
|
+
0,
|
|
89
|
+
family=socket.AF_INET,
|
|
90
|
+
type=socket.SOCK_STREAM,
|
|
91
|
+
flags=socket.AI_PASSIVE,
|
|
92
|
+
)
|
|
93
|
+
]
|
|
94
|
+
# Check if we can establish a gRPC connection using localhost first
|
|
95
|
+
# before trying other IPs. It has been observed that in some systems,
|
|
96
|
+
# although we can establish a test gRPC connection using one of the
|
|
97
|
+
# resolved IP addresses in addrinfo, PyFluent fails to connect to Fluent
|
|
98
|
+
# using that IP address. Using localhost usually helps in such cases.
|
|
99
|
+
all_ips.insert(0, "localhost")
|
|
100
|
+
|
|
101
|
+
for ip in all_ips:
|
|
92
102
|
port = get_free_port()
|
|
93
103
|
address = f"{ip}:{port}"
|
|
94
104
|
with _GrpcServer(address):
|