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.

Files changed (108) hide show
  1. ansys/fluent/core/__init__.py +48 -84
  2. ansys/fluent/core/codegen/allapigen.py +2 -2
  3. ansys/fluent/core/codegen/builtin_settingsgen.py +41 -13
  4. ansys/fluent/core/codegen/datamodelgen.py +3 -1
  5. ansys/fluent/core/codegen/print_fluent_version.py +2 -2
  6. ansys/fluent/core/codegen/settingsgen.py +18 -6
  7. ansys/fluent/core/codegen/tuigen.py +6 -5
  8. ansys/fluent/core/data_model_cache.py +2 -2
  9. ansys/fluent/core/docker/docker_compose.py +11 -9
  10. ansys/fluent/core/docker/utils.py +35 -0
  11. ansys/fluent/core/examples/downloads.py +8 -11
  12. ansys/fluent/core/exceptions.py +13 -1
  13. ansys/fluent/core/field_data_interfaces.py +239 -38
  14. ansys/fluent/core/file_session.py +167 -61
  15. ansys/fluent/core/fluent_connection.py +41 -26
  16. ansys/fluent/core/generated/api_tree/api_objects.json +1 -1
  17. ansys/fluent/core/generated/datamodel_231/flicing.py +40 -40
  18. ansys/fluent/core/generated/datamodel_231/meshing.py +231 -231
  19. ansys/fluent/core/generated/datamodel_232/flicing.py +50 -50
  20. ansys/fluent/core/generated/datamodel_232/meshing.py +189 -189
  21. ansys/fluent/core/generated/datamodel_241/flicing.py +30 -30
  22. ansys/fluent/core/generated/datamodel_241/meshing.py +290 -290
  23. ansys/fluent/core/generated/datamodel_242/flicing.py +50 -50
  24. ansys/fluent/core/generated/datamodel_242/meshing.py +331 -331
  25. ansys/fluent/core/generated/datamodel_242/part_management.py +6 -6
  26. ansys/fluent/core/generated/datamodel_251/flicing.py +65 -65
  27. ansys/fluent/core/generated/datamodel_251/meshing.py +300 -300
  28. ansys/fluent/core/generated/datamodel_251/part_management.py +6 -6
  29. ansys/fluent/core/generated/datamodel_252/flicing.py +25 -25
  30. ansys/fluent/core/generated/datamodel_252/meshing.py +382 -382
  31. ansys/fluent/core/generated/datamodel_252/part_management.py +10 -10
  32. ansys/fluent/core/generated/datamodel_261/flicing.py +45 -45
  33. ansys/fluent/core/generated/datamodel_261/meshing.py +454 -435
  34. ansys/fluent/core/generated/datamodel_261/part_management.py +5 -5
  35. ansys/fluent/core/generated/datamodel_261/preferences.py +7 -0
  36. ansys/fluent/core/generated/fluent_version_252.py +1 -1
  37. ansys/fluent/core/generated/fluent_version_261.py +3 -3
  38. ansys/fluent/core/generated/meshing/tui_261.py +54 -3
  39. ansys/fluent/core/generated/solver/settings_231.py +1 -0
  40. ansys/fluent/core/generated/solver/settings_231.pyi +3025 -1
  41. ansys/fluent/core/generated/solver/settings_232.py +1 -0
  42. ansys/fluent/core/generated/solver/settings_232.pyi +3425 -1
  43. ansys/fluent/core/generated/solver/settings_241.py +1 -0
  44. ansys/fluent/core/generated/solver/settings_241.pyi +4423 -1
  45. ansys/fluent/core/generated/solver/settings_242.py +1 -0
  46. ansys/fluent/core/generated/solver/settings_242.pyi +5474 -1
  47. ansys/fluent/core/generated/solver/settings_251.py +11 -0
  48. ansys/fluent/core/generated/solver/settings_251.pyi +6006 -1
  49. ansys/fluent/core/generated/solver/settings_252.py +11 -1
  50. ansys/fluent/core/generated/solver/settings_252.pyi +6782 -2
  51. ansys/fluent/core/generated/solver/settings_261.py +5592 -2740
  52. ansys/fluent/core/generated/solver/settings_261.pyi +10335 -1994
  53. ansys/fluent/core/generated/solver/settings_builtin.py +560 -38
  54. ansys/fluent/core/generated/solver/settings_builtin.pyi +24 -18
  55. ansys/fluent/core/generated/solver/tui_261.py +409 -285
  56. ansys/fluent/core/launcher/container_launcher.py +25 -6
  57. ansys/fluent/core/launcher/error_handler.py +1 -1
  58. ansys/fluent/core/launcher/fluent_container.py +97 -45
  59. ansys/fluent/core/launcher/launch_options.py +5 -4
  60. ansys/fluent/core/launcher/launcher.py +18 -2
  61. ansys/fluent/core/launcher/launcher_utils.py +63 -15
  62. ansys/fluent/core/launcher/pim_launcher.py +17 -3
  63. ansys/fluent/core/launcher/process_launch_string.py +3 -2
  64. ansys/fluent/core/launcher/server_info.py +7 -3
  65. ansys/fluent/core/launcher/slurm_launcher.py +4 -2
  66. ansys/fluent/core/launcher/standalone_launcher.py +6 -3
  67. ansys/fluent/core/launcher/watchdog.py +6 -6
  68. ansys/fluent/core/launcher/watchdog_exec +1 -1
  69. ansys/fluent/core/logger.py +3 -1
  70. ansys/fluent/core/module_config.py +358 -0
  71. ansys/fluent/core/pyfluent_warnings.py +9 -3
  72. ansys/fluent/core/report.py +2 -2
  73. ansys/fluent/core/search.py +34 -13
  74. ansys/fluent/core/services/__init__.py +2 -2
  75. ansys/fluent/core/services/api_upgrade.py +3 -2
  76. ansys/fluent/core/services/app_utilities.py +39 -0
  77. ansys/fluent/core/services/datamodel_se.py +4 -2
  78. ansys/fluent/core/services/deprecated_field_data.py +4 -4
  79. ansys/fluent/core/services/field_data.py +185 -49
  80. ansys/fluent/core/services/health_check.py +3 -1
  81. ansys/fluent/core/services/interceptors.py +8 -6
  82. ansys/fluent/core/services/reduction.py +16 -5
  83. ansys/fluent/core/services/settings.py +1 -0
  84. ansys/fluent/core/session.py +47 -4
  85. ansys/fluent/core/session_pure_meshing.py +6 -6
  86. ansys/fluent/core/session_pure_meshing.pyi +1 -0
  87. ansys/fluent/core/session_shared.py +4 -4
  88. ansys/fluent/core/session_solver.py +41 -10
  89. ansys/fluent/core/session_solver.pyi +1 -0
  90. ansys/fluent/core/session_utilities.py +7 -0
  91. ansys/fluent/core/solver/error_message.py +2 -2
  92. ansys/fluent/core/solver/flobject.py +192 -123
  93. ansys/fluent/core/solver/function/reduction.py +37 -9
  94. ansys/fluent/core/solver/settings_builtin_bases.py +3 -3
  95. ansys/fluent/core/solver/settings_builtin_data.py +7 -17
  96. ansys/fluent/core/streaming_services/datamodel_event_streaming.py +3 -2
  97. ansys/fluent/core/streaming_services/datamodel_streaming.py +3 -1
  98. ansys/fluent/core/streaming_services/events_streaming.py +2 -18
  99. ansys/fluent/core/system_coupling.py +3 -1
  100. ansys/fluent/core/utils/__init__.py +0 -7
  101. ansys/fluent/core/utils/data_transfer.py +3 -3
  102. ansys/fluent/core/utils/file_transfer_service.py +24 -15
  103. ansys/fluent/core/utils/fluent_version.py +4 -6
  104. ansys/fluent/core/utils/networking.py +21 -11
  105. {ansys_fluent_core-0.34.dev0.dist-info → ansys_fluent_core-0.35.dev0.dist-info}/METADATA +10 -11
  106. {ansys_fluent_core-0.34.dev0.dist-info → ansys_fluent_core-0.35.dev0.dist-info}/RECORD +108 -106
  107. {ansys_fluent_core-0.34.dev0.dist-info → ansys_fluent_core-0.35.dev0.dist-info}/WHEEL +1 -1
  108. {ansys_fluent_core-0.34.dev0.dist-info/licenses → ansys_fluent_core-0.35.dev0.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 _. Any ``?`` symbols are
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
- FluentVersion(float(deprecated_version)) <= FluentVersion.v222
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).is_active()
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
- return getattr(super(), name)
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
- # We don't get arguments-aliases from static-info yet.
1617
- argument_aliases_scm = obj.get_attr("arguments-aliases") or {}
1618
- argument_aliases = {}
1619
- for k, v in argument_aliases_scm.items():
1620
- argument_aliases[to_python_name(k)] = to_python_name(v.removeprefix("'"))
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).is_active()
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:
@@ -1705,6 +1730,8 @@ class BaseCommand(Action):
1705
1730
 
1706
1731
  def _execute_command(self, *args, **kwds):
1707
1732
  """Execute a command with the specified positional and keyword arguments."""
1733
+ from ansys.fluent.core import config
1734
+
1708
1735
  if self.flproxy.is_interactive_mode():
1709
1736
  prompt = self.flproxy.get_command_confirmation_prompt(
1710
1737
  self._parent.path, self.obj_name, **kwds
@@ -1721,12 +1748,16 @@ class BaseCommand(Action):
1721
1748
  print("Please enter 'y[es]' or 'n[o]'.")
1722
1749
  with self._while_executing_command():
1723
1750
  ret = self.flproxy.execute_cmd(self._parent.path, self.obj_name, **kwds)
1724
- if os.getenv("PYFLUENT_NO_FIX_PARAMETER_LIST_RETURN") != "1":
1725
- if (self._parent.path, self.obj_name) in [
1726
- ("parameters/input-parameters", "list"),
1727
- ("parameters/output-parameters", "list"),
1728
- ]:
1729
- ret = _fix_parameter_list_return(ret)
1751
+ if (
1752
+ not config.disable_parameter_list_return_fix
1753
+ and FluentVersion(self._version) <= FluentVersion.v252
1754
+ and self.path
1755
+ in [
1756
+ "parameters/input-parameters/list",
1757
+ "parameters/output-parameters/list",
1758
+ ]
1759
+ ):
1760
+ ret = _fix_parameter_list_return(ret)
1730
1761
  return ret
1731
1762
 
1732
1763
  def execute_command(self, *args, **kwds):
@@ -1764,13 +1795,6 @@ class BaseCommand(Action):
1764
1795
  assert_type(ret, base_t._state_type)
1765
1796
  return ret
1766
1797
 
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
1798
 
1775
1799
  # TODO: Remove this after parameter list() method is fixed from Fluent side
1776
1800
  def _fix_parameter_list_return(val):
@@ -1807,6 +1831,8 @@ class Command(BaseCommand):
1807
1831
 
1808
1832
  def __call__(self, **kwds):
1809
1833
  """Call a command with the specified keyword arguments."""
1834
+ if not self.is_active():
1835
+ raise InactiveObjectError(self.python_path)
1810
1836
  try:
1811
1837
  return self.execute_command(**kwds)
1812
1838
  except KeyboardInterrupt:
@@ -1819,6 +1845,8 @@ class CommandWithPositionalArgs(BaseCommand):
1819
1845
 
1820
1846
  def __call__(self, *args, **kwds):
1821
1847
  """Call a command with the specified positional and keyword arguments."""
1848
+ if not self.is_active():
1849
+ raise InactiveObjectError(self.python_path)
1822
1850
  try:
1823
1851
  return self.execute_command(*args, **kwds)
1824
1852
  except KeyboardInterrupt:
@@ -1831,6 +1859,8 @@ class Query(Action):
1831
1859
 
1832
1860
  def __call__(self, **kwds):
1833
1861
  """Call a query with the specified keyword arguments."""
1862
+ if not self.is_active():
1863
+ raise InactiveObjectError(self.python_path)
1834
1864
  kwds = _get_new_keywords(self, **kwds)
1835
1865
  scmKwds = {}
1836
1866
  for arg, value in kwds.items():
@@ -2027,6 +2057,33 @@ class AllowedValuesMixin:
2027
2057
  return []
2028
2058
 
2029
2059
 
2060
+ class _MaybeActiveString(str):
2061
+ """A string class with an is_active() method."""
2062
+
2063
+ def __new__(cls, value, is_active: Callable[[], bool]):
2064
+ return super().__new__(cls, value)
2065
+
2066
+ def __init__(self, value, is_active: Callable[[], bool]):
2067
+ super().__init__()
2068
+ self.is_active = is_active
2069
+
2070
+
2071
+ class _FlStringConstant:
2072
+ """A descriptor class to hold a constant string value."""
2073
+
2074
+ def __init__(self, value):
2075
+ self._value = value
2076
+
2077
+ def __get__(self, instance, owner):
2078
+ def is_active():
2079
+ return self._value in instance.allowed_values()
2080
+
2081
+ return _MaybeActiveString(self._value, is_active=is_active)
2082
+
2083
+ def __set__(self, instance, value):
2084
+ raise AttributeError("Cannot set a constant value.")
2085
+
2086
+
2030
2087
  _bases_by_class = {}
2031
2088
 
2032
2089
 
@@ -2111,8 +2168,11 @@ def get_cls(name, info, parent=None, version=None, parent_taboo=None):
2111
2168
  dct["_child_classes"] = {}
2112
2169
  cls = type(pname, bases, dct)
2113
2170
 
2114
- deprecated_version = info.get("deprecated_version", "")
2115
- cls._deprecated_version = deprecated_version
2171
+ deprecated_version = info.get("deprecated_version", None)
2172
+ if deprecated_version and float(deprecated_version) >= 22.2:
2173
+ cls._deprecated_version = deprecated_version
2174
+ else:
2175
+ cls._deprecated_version = ""
2116
2176
 
2117
2177
  taboo = set(dir(cls))
2118
2178
  taboo |= set(
@@ -2156,7 +2216,6 @@ def get_cls(name, info, parent=None, version=None, parent_taboo=None):
2156
2216
  commands = info.get("commands")
2157
2217
  if commands:
2158
2218
  commands.pop("exit", None)
2159
- commands.pop("switch-to-meshing-mode", None)
2160
2219
  if commands and not user_creatable:
2161
2220
  commands.pop("create", None)
2162
2221
  if commands:
@@ -2195,14 +2254,14 @@ def get_cls(name, info, parent=None, version=None, parent_taboo=None):
2195
2254
  child_aliases = info.get("child-aliases") or info.get("child_aliases", {})
2196
2255
  command_aliases = info.get("command-aliases") or info.get("command_aliases", {})
2197
2256
  query_aliases = info.get("query-aliases") or info.get("query_aliases", {})
2198
- argument_aliases = info.get("arguments-aliases") or info.get(
2257
+ arguments_aliases = info.get("arguments-aliases") or info.get(
2199
2258
  "arguments_aliases", {}
2200
2259
  )
2201
- if child_aliases or command_aliases or query_aliases or argument_aliases:
2260
+ if child_aliases or command_aliases or query_aliases or arguments_aliases:
2202
2261
  cls._child_aliases = {}
2203
2262
  # No need to differentiate in the Python implementation
2204
2263
  for k, v in (
2205
- child_aliases | command_aliases | query_aliases | argument_aliases
2264
+ child_aliases | command_aliases | query_aliases | arguments_aliases
2206
2265
  ).items():
2207
2266
  # Storing the original name as we don't have any other way
2208
2267
  # to recover it at runtime.
@@ -2213,6 +2272,16 @@ def get_cls(name, info, parent=None, version=None, parent_taboo=None):
2213
2272
  k,
2214
2273
  )
2215
2274
 
2275
+ allowed_values = info.get("allowed-values") or info.get("allowed_values", [])
2276
+ if allowed_values:
2277
+ for allowed_value in allowed_values:
2278
+ setattr(
2279
+ cls,
2280
+ to_constant_name(allowed_value),
2281
+ _FlStringConstant(allowed_value),
2282
+ )
2283
+ cls._allowed_values = allowed_values
2284
+
2216
2285
  except Exception:
2217
2286
  print(
2218
2287
  f"Unable to construct class for '{name}' of "
@@ -2259,16 +2328,16 @@ def get_root(
2259
2328
  RuntimeError
2260
2329
  If hash values are inconsistent.
2261
2330
  """
2262
- from ansys.fluent.core import CODEGEN_OUTDIR, utils
2331
+ from ansys.fluent.core import config, utils
2263
2332
 
2264
- if os.getenv("PYFLUENT_USE_RUNTIME_PYTHON_CLASSES") == "1":
2333
+ if config.use_runtime_python_classes:
2265
2334
  obj_info = flproxy.get_static_info()
2266
2335
  root_cls, _ = get_cls("", obj_info, version=version)
2267
2336
  else:
2268
2337
  try:
2269
2338
  settings = utils.load_module(
2270
2339
  f"settings_{version}",
2271
- CODEGEN_OUTDIR / "solver" / f"settings_{version}.py",
2340
+ config.codegen_outdir / "solver" / f"settings_{version}.py",
2272
2341
  )
2273
2342
  root_cls = settings.root
2274
2343
  warning_for_fluent_dev_version(version)
@@ -74,16 +74,35 @@ Examples
74
74
  >>> vsquared.definition = "VelocityMagnitude ** 2"
75
75
  >>> reduction.minimum(
76
76
  ... expr = vsquared,
77
- ... locations = [
78
- ... solver1.setup.boundary_conditions.pressure_outlet,
79
- ... solver2.setup.boundary_conditions.pressure_outlet
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
  -------
@@ -52,9 +52,9 @@ def _get_settings_root(settings_source: SettingsBase | Solver):
52
52
 
53
53
 
54
54
  def _get_settings_obj(settings_root, builtin_settings_obj):
55
- builtin_cls_name = builtin_settings_obj.__class__.__name__
55
+ builtin_cls_db_name = builtin_settings_obj.__class__._db_name
56
56
  obj = settings_root
57
- path = DATA[builtin_cls_name][1]
57
+ path = DATA[builtin_cls_db_name][1]
58
58
  found_path = None
59
59
  if isinstance(path, dict):
60
60
  version = FluentVersion(obj._version)
@@ -63,7 +63,7 @@ def _get_settings_obj(settings_root, builtin_settings_obj):
63
63
  found_path = p
64
64
  break
65
65
  if found_path is None:
66
- raise RuntimeError(f"{builtin_cls_name} is not supported in {version}.")
66
+ raise RuntimeError(f"{builtin_cls_db_name} is not supported in {version}.")
67
67
  elif isinstance(path, str):
68
68
  found_path = path
69
69
  comps = found_path.split(".")
@@ -225,26 +225,14 @@ DATA = {
225
225
  "VelocityInlet": ("NamedObject", "setup.boundary_conditions.velocity_inlet"),
226
226
  "WallBoundaries": ("Singleton", "setup.boundary_conditions.wall"),
227
227
  "WallBoundary": ("NamedObject", "setup.boundary_conditions.wall"),
228
- "NonReflectingBoundaries": (
229
- "Singleton",
230
- {
231
- since(FluentVersion.v241): "setup.boundary_conditions.non_reflecting_bc",
232
- },
233
- ),
234
228
  "NonReflectingBoundary": (
235
- "NamedObject",
236
- {
237
- since(FluentVersion.v241): "setup.boundary_conditions.non_reflecting_bc",
238
- },
239
- ),
240
- "PerforatedWallBoundaries": (
241
229
  "Singleton",
242
230
  {
243
- since(FluentVersion.v241): "setup.boundary_conditions.perforated_wall",
231
+ since(FluentVersion.v241): "setup.boundary_conditions.non_reflecting_bc",
244
232
  },
245
233
  ),
246
234
  "PerforatedWallBoundary": (
247
- "NamedObject",
235
+ "Singleton",
248
236
  {
249
237
  since(FluentVersion.v241): "setup.boundary_conditions.perforated_wall",
250
238
  },
@@ -729,23 +717,25 @@ DATA = {
729
717
  "ReadData": ("Command", "file.read_data"),
730
718
  "ReadCaseData": ("Command", "file.read_case_data"),
731
719
  "WriteCase": (
732
- "Singleton",
720
+ "Command",
733
721
  {
734
722
  since(FluentVersion.v241): "file.write_case",
735
723
  },
736
724
  ),
737
725
  "WriteData": (
738
- "Singleton",
726
+ "Command",
739
727
  {
740
728
  since(FluentVersion.v241): "file.write_data",
741
729
  },
742
730
  ),
743
731
  "WriteCaseData": (
744
- "Singleton",
732
+ "Command",
745
733
  {
746
734
  since(FluentVersion.v241): "file.write_case_data",
747
735
  },
748
736
  ),
749
737
  "Initialize": ("Command", "solution.initialization.initialize"),
750
738
  "Calculate": ("Command", "solution.run_calculation.calculate"),
739
+ "Iterate": ("Command", "solution.run_calculation.iterate"),
740
+ "DualTimeIterate": ("Command", "solution.run_calculation.dual_time_iterate"),
751
741
  }