ansys-fluent-core 0.27.dev1__py3-none-any.whl → 0.28.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 (188) hide show
  1. ansys/fluent/core/__init__.py +22 -9
  2. ansys/fluent/core/_version.py +5 -2
  3. ansys/fluent/core/codegen/__init__.py +0 -3
  4. ansys/fluent/core/codegen/allapigen.py +1 -5
  5. ansys/fluent/core/codegen/builtin_settingsgen.py +44 -10
  6. ansys/fluent/core/codegen/datamodelgen.py +53 -12
  7. ansys/fluent/core/codegen/settingsgen.py +21 -12
  8. ansys/fluent/core/codegen/settingsgen_old.py +2 -2
  9. ansys/fluent/core/codegen/tuigen.py +1 -1
  10. ansys/fluent/core/codegen/write_settings_yaml.py +3 -4
  11. ansys/fluent/core/data_model_cache.py +132 -70
  12. ansys/fluent/core/docs/README.rst +2 -2
  13. ansys/fluent/core/examples/downloads.py +3 -5
  14. ansys/fluent/core/exceptions.py +1 -0
  15. ansys/fluent/core/file_session.py +59 -131
  16. ansys/fluent/core/filereader/case_file.py +17 -17
  17. ansys/fluent/core/filereader/casereader.py +2 -1
  18. ansys/fluent/core/filereader/data_file.py +7 -7
  19. ansys/fluent/core/filereader/lispy.py +6 -1
  20. ansys/fluent/core/fluent_connection.py +35 -7
  21. ansys/fluent/core/generated/api_tree/api_objects.json +1 -1
  22. ansys/fluent/core/generated/datamodel_222/PMFileManagement.py +2 -2
  23. ansys/fluent/core/generated/datamodel_222/PartManagement.py +28 -28
  24. ansys/fluent/core/generated/datamodel_222/meshing.py +301 -301
  25. ansys/fluent/core/generated/datamodel_222/workflow.py +9 -9
  26. ansys/fluent/core/generated/datamodel_231/PMFileManagement.py +2 -2
  27. ansys/fluent/core/generated/datamodel_231/PartManagement.py +55 -55
  28. ansys/fluent/core/generated/datamodel_231/flicing.py +51 -51
  29. ansys/fluent/core/generated/datamodel_231/meshing.py +317 -317
  30. ansys/fluent/core/generated/datamodel_231/solverworkflow.py +51 -51
  31. ansys/fluent/core/generated/datamodel_231/workflow.py +9 -9
  32. ansys/fluent/core/generated/datamodel_232/PMFileManagement.py +2 -2
  33. ansys/fluent/core/generated/datamodel_232/PartManagement.py +55 -55
  34. ansys/fluent/core/generated/datamodel_232/flicing.py +51 -51
  35. ansys/fluent/core/generated/datamodel_232/meshing.py +335 -335
  36. ansys/fluent/core/generated/datamodel_232/solverworkflow.py +58 -58
  37. ansys/fluent/core/generated/datamodel_232/workflow.py +9 -9
  38. ansys/fluent/core/generated/datamodel_241/PMFileManagement.py +2 -2
  39. ansys/fluent/core/generated/datamodel_241/PartManagement.py +57 -57
  40. ansys/fluent/core/generated/datamodel_241/flicing.py +51 -51
  41. ansys/fluent/core/generated/datamodel_241/meshing.py +361 -361
  42. ansys/fluent/core/generated/datamodel_241/solverworkflow.py +58 -58
  43. ansys/fluent/core/generated/datamodel_241/workflow.py +9 -9
  44. ansys/fluent/core/generated/datamodel_242/MeshingUtilities.py +240 -240
  45. ansys/fluent/core/generated/datamodel_242/PMFileManagement.py +2 -2
  46. ansys/fluent/core/generated/datamodel_242/PartManagement.py +60 -60
  47. ansys/fluent/core/generated/datamodel_242/flicing.py +51 -51
  48. ansys/fluent/core/generated/datamodel_242/meshing.py +371 -371
  49. ansys/fluent/core/generated/datamodel_242/solverworkflow.py +58 -58
  50. ansys/fluent/core/generated/datamodel_242/workflow.py +9 -9
  51. ansys/fluent/core/generated/datamodel_251/MeshingUtilities.py +244 -244
  52. ansys/fluent/core/generated/datamodel_251/PMFileManagement.py +2 -2
  53. ansys/fluent/core/generated/datamodel_251/PartManagement.py +60 -60
  54. ansys/fluent/core/generated/datamodel_251/flicing.py +51 -51
  55. ansys/fluent/core/generated/datamodel_251/meshing.py +384 -382
  56. ansys/fluent/core/generated/datamodel_251/preferences.py +7 -0
  57. ansys/fluent/core/generated/datamodel_251/solverworkflow.py +58 -58
  58. ansys/fluent/core/generated/datamodel_251/workflow.py +10 -10
  59. ansys/fluent/core/generated/datamodel_252/MeshingUtilities.py +3664 -0
  60. ansys/fluent/core/generated/datamodel_252/PMFileManagement.py +288 -0
  61. ansys/fluent/core/generated/datamodel_252/PartManagement.py +2588 -0
  62. ansys/fluent/core/generated/datamodel_252/flicing.py +7972 -0
  63. ansys/fluent/core/generated/datamodel_252/meshing.py +2644 -0
  64. ansys/fluent/core/generated/datamodel_252/preferences.py +2760 -0
  65. ansys/fluent/core/generated/datamodel_252/solverworkflow.py +479 -0
  66. ansys/fluent/core/generated/datamodel_252/workflow.py +466 -0
  67. ansys/fluent/core/generated/fluent_version_251.py +4 -4
  68. ansys/fluent/core/generated/fluent_version_252.py +5 -0
  69. ansys/fluent/core/generated/meshing/tui_251.py +1139 -1179
  70. ansys/fluent/core/generated/meshing/tui_252.py +10181 -0
  71. ansys/fluent/core/generated/solver/settings_222.py +3 -3
  72. ansys/fluent/core/generated/solver/settings_231.py +4 -4
  73. ansys/fluent/core/generated/solver/settings_232.py +5 -5
  74. ansys/fluent/core/generated/solver/settings_241.py +5 -5
  75. ansys/fluent/core/generated/solver/settings_242.py +1185 -1185
  76. ansys/fluent/core/generated/solver/settings_251.py +1847 -1652
  77. ansys/fluent/core/generated/solver/settings_251.pyi +237 -211
  78. ansys/fluent/core/generated/solver/settings_252.py +90369 -0
  79. ansys/fluent/core/generated/solver/settings_252.pyi +63778 -0
  80. ansys/fluent/core/generated/solver/settings_builtin.py +612 -1
  81. ansys/fluent/core/generated/solver/settings_builtin.pyi +235 -0
  82. ansys/fluent/core/generated/solver/tui_251.py +2283 -2103
  83. ansys/fluent/core/generated/solver/tui_252.py +37720 -0
  84. ansys/fluent/core/journaling.py +1 -1
  85. ansys/fluent/core/launcher/error_handler.py +3 -0
  86. ansys/fluent/core/launcher/fluent_container.py +5 -0
  87. ansys/fluent/core/launcher/launcher.py +1 -2
  88. ansys/fluent/core/launcher/launcher_utils.py +17 -6
  89. ansys/fluent/core/launcher/process_launch_string.py +3 -3
  90. ansys/fluent/core/launcher/pyfluent_enums.py +1 -1
  91. ansys/fluent/core/launcher/slurm_launcher.py +2 -1
  92. ansys/fluent/core/launcher/standalone_launcher.py +11 -5
  93. ansys/fluent/core/launcher/watchdog.py +1 -1
  94. ansys/fluent/core/launcher/watchdog_exec +6 -3
  95. ansys/fluent/core/logging.py +1 -5
  96. ansys/fluent/core/parametric.py +6 -3
  97. ansys/fluent/core/post_objects/meta.py +1 -39
  98. ansys/fluent/core/post_objects/post_helper.py +4 -3
  99. ansys/fluent/core/post_objects/post_object_definitions.py +12 -7
  100. ansys/fluent/core/post_objects/post_objects_container.py +39 -2
  101. ansys/fluent/core/rpvars.py +2 -1
  102. ansys/fluent/core/scheduler/machine_list.py +3 -1
  103. ansys/fluent/core/search.py +109 -262
  104. ansys/fluent/core/services/__init__.py +3 -0
  105. ansys/fluent/core/services/api_upgrade.py +1 -0
  106. ansys/fluent/core/services/batch_ops.py +3 -1
  107. ansys/fluent/core/services/datamodel_se.py +37 -30
  108. ansys/fluent/core/services/datamodel_tui.py +8 -3
  109. ansys/fluent/core/services/deprecated_field_data.py +691 -0
  110. ansys/fluent/core/services/field_data.py +67 -357
  111. ansys/fluent/core/services/interceptors.py +6 -4
  112. ansys/fluent/core/services/reduction.py +1 -2
  113. ansys/fluent/core/services/scheme_eval.py +2 -3
  114. ansys/fluent/core/services/solution_variables.py +46 -48
  115. ansys/fluent/core/session.py +6 -4
  116. ansys/fluent/core/session_meshing.pyi +5 -0
  117. ansys/fluent/core/session_pure_meshing.pyi +4 -1
  118. ansys/fluent/core/session_solver_lite.py +2 -1
  119. ansys/fluent/core/solver/flobject.py +179 -207
  120. ansys/fluent/core/solver/flunits.py +65 -56
  121. ansys/fluent/core/solver/function/reduction.py +9 -29
  122. ansys/fluent/core/solver/settings_builtin_bases.py +28 -22
  123. ansys/fluent/core/solver/settings_builtin_data.py +105 -1
  124. ansys/fluent/core/solver/settings_external.py +0 -28
  125. ansys/fluent/core/streaming_services/field_data_streaming.py +1 -0
  126. ansys/fluent/core/streaming_services/monitor_streaming.py +0 -1
  127. ansys/fluent/core/systemcoupling.py +145 -14
  128. ansys/fluent/core/utils/__init__.py +18 -2
  129. ansys/fluent/core/utils/dump_session_data.py +7 -4
  130. ansys/fluent/core/utils/execution.py +2 -2
  131. ansys/fluent/core/utils/file_transfer_service.py +37 -42
  132. ansys/fluent/core/utils/fluent_version.py +20 -2
  133. ansys/fluent/core/utils/networking.py +39 -1
  134. ansys/fluent/core/workflow.py +3 -15
  135. ansys/fluent/tests/conftest.py +89 -7
  136. ansys/fluent/tests/fluent/test_version/test.py +2 -0
  137. ansys/fluent/tests/fluent_fixtures.py +195 -0
  138. ansys/fluent/tests/integration/test_optislang/test_optislang_integration.py +7 -7
  139. ansys/fluent/tests/parametric/test_parametric_workflow.py +14 -4
  140. ansys/fluent/tests/test_builtin_settings.py +28 -0
  141. ansys/fluent/tests/test_cad_to_post_ftm.py +1 -3
  142. ansys/fluent/tests/test_cad_to_post_wtm.py +1 -1
  143. ansys/fluent/tests/test_casereader.py +1 -1
  144. ansys/fluent/tests/test_codegen.py +116 -6
  145. ansys/fluent/tests/test_data_model_cache.py +1 -1
  146. ansys/fluent/tests/test_datamodel_service.py +14 -19
  147. ansys/fluent/tests/test_field_data.py +93 -45
  148. ansys/fluent/tests/test_file_session.py +32 -29
  149. ansys/fluent/tests/test_flobject.py +16 -58
  150. ansys/fluent/tests/test_fluent_fixes.py +5 -5
  151. ansys/fluent/tests/test_fluent_session.py +11 -8
  152. ansys/fluent/tests/test_fluent_version.py +1 -1
  153. ansys/fluent/tests/test_launcher.py +22 -5
  154. ansys/fluent/tests/test_launcher_remote.py +80 -4
  155. ansys/fluent/tests/test_meshing_utilities.py +93 -44
  156. ansys/fluent/tests/test_meshing_workflow.py +6 -6
  157. ansys/fluent/tests/test_meshingmode/test_meshing_launch.py +1 -1
  158. ansys/fluent/tests/test_new_meshing_workflow.py +42 -3
  159. ansys/fluent/tests/test_preferences.py +6 -6
  160. ansys/fluent/tests/test_reduction.py +61 -30
  161. ansys/fluent/tests/test_rp_vars.py +1 -1
  162. ansys/fluent/tests/test_search.py +53 -200
  163. ansys/fluent/tests/test_session.py +18 -13
  164. ansys/fluent/tests/test_settings_api.py +93 -29
  165. ansys/fluent/tests/test_settings_reader.py +1 -1
  166. ansys/fluent/tests/test_solver_monitors.py +1 -1
  167. ansys/fluent/tests/test_solvermode/test_calculationactivities.py +4 -4
  168. ansys/fluent/tests/test_solvermode/test_controls.py +3 -3
  169. ansys/fluent/tests/test_solvermode/test_methods.py +1 -1
  170. ansys/fluent/tests/test_solvermode/test_models.py +3 -3
  171. ansys/fluent/tests/test_systemcoupling.py +33 -5
  172. ansys/fluent/tests/test_topy.py +2 -2
  173. ansys/fluent/tests/test_tui_api.py +5 -5
  174. ansys/fluent/tests/test_utils.py +1 -1
  175. {ansys_fluent_core-0.27.dev1.dist-info → ansys_fluent_core-0.28.dev0.dist-info}/METADATA +6 -17
  176. ansys_fluent_core-0.28.dev0.dist-info/RECORD +291 -0
  177. ansys/fluent/core/generated/api_tree_222.pickle +0 -0
  178. ansys/fluent/core/generated/api_tree_231.pickle +0 -0
  179. ansys/fluent/core/generated/api_tree_232.pickle +0 -0
  180. ansys/fluent/core/generated/api_tree_241.pickle +0 -0
  181. ansys/fluent/core/generated/api_tree_242.pickle +0 -0
  182. ansys/fluent/core/generated/api_tree_251.pickle +0 -0
  183. ansys/fluent/tests/test_tests_util.py +0 -47
  184. ansys/fluent/tests/util/__init__.py +0 -38
  185. ansys_fluent_core-0.27.dev1.dist-info/RECORD +0 -283
  186. {ansys_fluent_core-0.27.dev1.dist-info → ansys_fluent_core-0.28.dev0.dist-info}/AUTHORS +0 -0
  187. {ansys_fluent_core-0.27.dev1.dist-info → ansys_fluent_core-0.28.dev0.dist-info}/LICENSE +0 -0
  188. {ansys_fluent_core-0.27.dev1.dist-info → ansys_fluent_core-0.28.dev0.dist-info}/WHEEL +0 -0
@@ -48,10 +48,13 @@ import warnings
48
48
  import weakref
49
49
  from zipimport import zipimporter
50
50
 
51
+ import ansys.fluent.core as pyfluent
51
52
  from ansys.fluent.core.utils.fluent_version import FluentVersion
52
53
  from ansys.fluent.core.warnings import PyFluentDeprecationWarning, PyFluentUserWarning
53
54
 
55
+ from .error_message import allowed_name_error_message, allowed_values_error
54
56
  from .flunits import UnhandledQuantity, get_si_unit_for_fluent_quantity
57
+ from .settings_external import expand_api_file_argument
55
58
 
56
59
 
57
60
  def _ansys_units():
@@ -64,11 +67,6 @@ def _ansys_units():
64
67
  pass
65
68
 
66
69
 
67
- import ansys.fluent.core as pyfluent
68
-
69
- from .error_message import allowed_name_error_message, allowed_values_error
70
- from .settings_external import expand_api_file_argument, use_search
71
-
72
70
  settings_logger = logging.getLogger("pyfluent.settings_api")
73
71
 
74
72
 
@@ -76,6 +74,7 @@ class InactiveObjectError(RuntimeError):
76
74
  """Inactive object access."""
77
75
 
78
76
  def __init__(self, python_path):
77
+ """Initialize InactiveObjectError."""
79
78
  super().__init__(f"'{python_path}' is currently inactive.")
80
79
 
81
80
 
@@ -173,6 +172,38 @@ def to_python_name(fluent_name: str) -> str:
173
172
  return name
174
173
 
175
174
 
175
+ def _get_python_path_comps(obj):
176
+ """Get python path components for traversing class hierarchy."""
177
+ comps = []
178
+ while obj:
179
+ python_name = obj._python_name
180
+ obj = obj._parent
181
+ if isinstance(obj, (NamedObject, ListObject)):
182
+ comps.append(obj._python_name)
183
+ obj = obj._parent
184
+ else:
185
+ comps.append(python_name)
186
+ comps.reverse()
187
+ return comps[1:]
188
+
189
+
190
+ def _get_class_from_paths(root_cls, some_path: list[str], other_path: list[str]):
191
+ """Get the class for the given alias path."""
192
+ parent_count = 0
193
+ while other_path[0] == "..":
194
+ parent_count += 1
195
+ other_path.pop(0)
196
+ for _ in range(parent_count):
197
+ some_path.pop()
198
+ full_path = some_path + other_path
199
+ cls = root_cls
200
+ for comp in full_path:
201
+ cls = cls._child_classes[comp]
202
+ if issubclass(cls, (NamedObject, ListObject)):
203
+ cls = cls.child_object_type
204
+ return cls, full_path
205
+
206
+
176
207
  class Base:
177
208
  """Provides the base class for settings and command objects.
178
209
 
@@ -467,6 +498,9 @@ class Numerical(Property):
467
498
  return None if isinstance(val, bool) else val
468
499
 
469
500
 
501
+ QuantityT = TypeVar("QuantityT")
502
+
503
+
470
504
  class RealNumerical(Numerical):
471
505
  """A ``RealNumerical`` object representing a real value setting, including single
472
506
  real values and containers of real values, such as lists.
@@ -483,7 +517,7 @@ class RealNumerical(Numerical):
483
517
  Get the units string.
484
518
  """
485
519
 
486
- def as_quantity(self) -> ansys.units.Quantity | None:
520
+ def as_quantity(self) -> QuantityT | None:
487
521
  """Get the state of the object as an ansys.units.Quantity."""
488
522
  error = None
489
523
  if not _ansys_units():
@@ -644,43 +678,6 @@ def _create_child(cls, name, parent: weakref.CallableProxyType, alias_path=None)
644
678
  return cls(name, parent)
645
679
 
646
680
 
647
- def _combine_set_states(states: List[Tuple[str, StateT]]) -> Tuple[str, StateT]:
648
- """Combines multiple set-states into a single set-state at a common parent path.
649
-
650
- Parameters
651
- ----------
652
- states : list[tuple[str, StateT]]
653
- List of (<path>, <state>) tuples.
654
-
655
- Returns
656
- -------
657
- tuple[str, StateT]
658
- Common parent path, combined state.
659
- """
660
- paths, _ = zip(*states)
661
- common_path = []
662
- paths = [path.split("/") for path in paths]
663
- for comps in zip(*paths):
664
- if len(set(comps)) == 1:
665
- common_path.append(comps[0])
666
- else:
667
- break
668
- combined_state = {}
669
- for path, state in states:
670
- comps = path.split("/")
671
- comps = comps[len(common_path) :]
672
- if comps:
673
- if not isinstance(combined_state, dict):
674
- combined_state = {}
675
- obj = combined_state
676
- for comp in comps[:-1]:
677
- obj = obj.setdefault(comp, {})
678
- obj[comps[-1]] = state
679
- else:
680
- combined_state = state
681
- return "/".join(common_path), combined_state
682
-
683
-
684
681
  class SettingsBase(Base, Generic[StateT]):
685
682
  """Base class for settings objects.
686
683
 
@@ -694,7 +691,7 @@ class SettingsBase(Base, Generic[StateT]):
694
691
  """
695
692
 
696
693
  @classmethod
697
- def to_scheme_keys(cls, value: StateT) -> StateT:
694
+ def to_scheme_keys(cls, value: StateT, root_cls, path: list[str]) -> StateT:
698
695
  """Convert value to have keys with scheme names.
699
696
 
700
697
  This is overridden in the ``Group``, ``NamedObject``, and
@@ -719,63 +716,6 @@ class SettingsBase(Base, Generic[StateT]):
719
716
  """Get the state of the object."""
720
717
  return self.to_python_keys(self.flproxy.get_var(self.path))
721
718
 
722
- # Following is not a classmethod, as parent (required to support ".." in alias-path)
723
- # is available only at the instance level.
724
- def _unalias(self, cls, value):
725
- """Unalias the given value."""
726
- if isinstance(value, collections.abc.Mapping):
727
- ret = {}
728
- outer_set_states = []
729
- for k, v in value.items():
730
- if hasattr(cls, "_child_aliases") and k in cls._child_aliases:
731
- alias = cls._child_aliases[k]
732
- comps = alias.split("/")
733
- if comps[0] == "..":
734
- outer_obj = self
735
- while comps[0] == "..":
736
- outer_obj = outer_obj.parent
737
- comps = comps[1:]
738
- for comp in comps:
739
- try:
740
- outer_obj = getattr(outer_obj, comp)
741
- except InactiveObjectError:
742
- outer_obj = super(
743
- SettingsBase, outer_obj
744
- ).__getattribute__(comp)
745
- outer_set_states.append((outer_obj, v))
746
- else:
747
- ret_alias = ret
748
- aliased_cls = cls
749
- obj = self
750
- for i, comp in enumerate(comps):
751
- aliased_cls = aliased_cls._child_classes[comp]
752
- try:
753
- obj = getattr(obj, comp)
754
- except InactiveObjectError:
755
- obj = super(SettingsBase, obj).__getattribute__(comp)
756
- if i == len(comps) - 1:
757
- ret_alias[comp], o_set_states = obj._unalias(
758
- aliased_cls, v
759
- )
760
- outer_set_states.extend(o_set_states)
761
- else:
762
- ret_alias = ret_alias.setdefault(comp, {})
763
- else:
764
- if issubclass(cls, Group):
765
- ccls = cls._child_classes[k]
766
- try:
767
- cobj = getattr(self, k)
768
- except InactiveObjectError:
769
- cobj = super(SettingsBase, self).__getattribute__(k)
770
- ret[k], o_set_states = cobj._unalias(ccls, v)
771
- outer_set_states.extend(o_set_states)
772
- else:
773
- ret[k], o_set_states = self._unalias(cls, v)
774
- outer_set_states.extend(o_set_states)
775
- return ret, outer_set_states
776
- else:
777
- return value, []
778
-
779
719
  def set_state(self, state: StateT | None = None, **kwargs):
780
720
  """Set the state of the object."""
781
721
  with self._while_setting_state():
@@ -784,17 +724,14 @@ class SettingsBase(Base, Generic[StateT]):
784
724
  ):
785
725
  self.value.set_state(state, **kwargs)
786
726
  else:
787
- state, outer_set_states = self._unalias(self.__class__, kwargs or state)
788
- if outer_set_states:
789
- set_states = []
790
- if state:
791
- set_states.append((self.path, self.to_scheme_keys(state)))
792
- for obj, state in outer_set_states:
793
- set_states.append((obj.path, obj.to_scheme_keys(state)))
794
- path, state = _combine_set_states(set_states)
795
- self.flproxy.set_var(path, state)
796
- else:
797
- self.flproxy.set_var(self.path, self.to_scheme_keys(state))
727
+ self.flproxy.set_var(
728
+ self.path,
729
+ self.to_scheme_keys(
730
+ kwargs or state,
731
+ self._root.__class__,
732
+ _get_python_path_comps(self),
733
+ ),
734
+ )
798
735
 
799
736
  @staticmethod
800
737
  def _print_state_helper(state, out, indent=0, indent_factor=2):
@@ -1020,7 +957,7 @@ class Group(SettingsBase[DictStateType]):
1020
957
  return self.get_state()
1021
958
 
1022
959
  @classmethod
1023
- def to_scheme_keys(cls, value):
960
+ def to_scheme_keys(cls, value, root_cls, path: list[str]):
1024
961
  """Convert value to have keys with scheme names.
1025
962
 
1026
963
  Raises
@@ -1033,7 +970,15 @@ class Group(SettingsBase[DictStateType]):
1033
970
  for k, v in value.items():
1034
971
  if k in cls.child_names:
1035
972
  ccls = cls._child_classes[k]
1036
- ret[ccls.fluent_name] = ccls.to_scheme_keys(v)
973
+ ret[ccls.fluent_name] = ccls.to_scheme_keys(v, root_cls, path + [k])
974
+ elif k in cls._child_aliases:
975
+ alias, scm_alias_name = cls._child_aliases[k]
976
+ alias_cls, alias_path = _get_class_from_paths(
977
+ root_cls, path.copy(), alias.split("/")
978
+ )
979
+ ret[scm_alias_name] = alias_cls.to_scheme_keys(
980
+ v, root_cls, alias_path
981
+ )
1037
982
  else:
1038
983
  raise RuntimeError("Key '" + str(k) + "' is invalid")
1039
984
  return ret
@@ -1053,7 +998,7 @@ class Group(SettingsBase[DictStateType]):
1053
998
  ret[mname] = ccls.to_python_keys(mvalue)
1054
999
  return ret
1055
1000
  else:
1056
- return value
1001
+ return {}
1057
1002
 
1058
1003
  _child_classes = {}
1059
1004
  child_names = []
@@ -1120,6 +1065,7 @@ class Group(SettingsBase[DictStateType]):
1120
1065
  raise InactiveObjectError(self.python_path)
1121
1066
  alias = super().__getattribute__("_child_aliases").get(name)
1122
1067
  if alias:
1068
+ alias = alias[0]
1123
1069
  alias_obj = self._child_alias_objs.get(name)
1124
1070
  if alias_obj is None:
1125
1071
  obj = self.find_object(alias)
@@ -1133,27 +1079,18 @@ class Group(SettingsBase[DictStateType]):
1133
1079
  attr._check_stable()
1134
1080
  return attr
1135
1081
  except AttributeError as ex:
1136
- modified_search_results = []
1137
- if use_search(
1138
- codegen_outdir=pyfluent.CODEGEN_OUTDIR,
1139
- version=super().__getattribute__("version"),
1140
- ):
1141
- search_results = pyfluent.utils._search(
1142
- word=name,
1143
- search_root=self,
1144
- match_case=False,
1145
- match_whole_word=False,
1146
- )
1147
- if search_results:
1148
- for search_result in search_results:
1149
- search_result = search_result.replace(
1150
- "<search_root>", self.__class__.__name__
1151
- )
1152
- modified_search_results.append(search_result)
1082
+ pyfluent.PRINT_SEARCH_RESULTS = False
1083
+ search_results = pyfluent.utils.search(
1084
+ search_string=name,
1085
+ match_case=False,
1086
+ match_whole_word=False,
1087
+ )
1088
+ pyfluent.PRINT_SEARCH_RESULTS = True
1089
+ results = search_results if search_results else []
1153
1090
  error_msg = allowed_name_error_message(
1154
1091
  trial_name=name,
1155
1092
  message=ex.args[0],
1156
- search_results=modified_search_results,
1093
+ search_results=results,
1157
1094
  )
1158
1095
  ex.args = (error_msg,)
1159
1096
  raise
@@ -1249,18 +1186,14 @@ class WildcardPath(Group):
1249
1186
  # get_state example: a.b["*"].c.d.get_state() == {"<bN>" {"c": {"d": <d_value>}}}
1250
1187
  # set_state example: a.b["*"].set_state({"c": {"d": <d_value>}})
1251
1188
 
1252
- def to_scheme_keys(self, value):
1189
+ def to_scheme_keys(self, value, root_cls, path):
1253
1190
  """Convert value to have keys with scheme names."""
1254
- return self._settings_cls.to_scheme_keys(value)
1191
+ return self._settings_cls.to_scheme_keys(value, root_cls, path)
1255
1192
 
1256
1193
  def to_python_keys(self, value):
1257
1194
  """Convert value to have keys with Python names."""
1258
1195
  return self._state_cls.to_python_keys(value)
1259
1196
 
1260
- def _unalias(self, cls, value):
1261
- # Not yet implemented
1262
- return value, []
1263
-
1264
1197
 
1265
1198
  class NamedObjectWildcardPath(WildcardPath):
1266
1199
  """WildcardPath at a NamedObject path, so it can be looked up by wildcard again."""
@@ -1312,12 +1245,12 @@ class NamedObject(SettingsBase[DictStateType], Generic[ChildTypeT]):
1312
1245
  )
1313
1246
 
1314
1247
  @classmethod
1315
- def to_scheme_keys(cls, value):
1248
+ def to_scheme_keys(cls, value, root_cls, path: list[str]):
1316
1249
  """Convert value to have keys with scheme names."""
1317
1250
  if isinstance(value, collections.abc.Mapping):
1318
1251
  ret = {}
1319
1252
  for k, v in value.items():
1320
- ret[k] = cls.child_object_type.to_scheme_keys(v)
1253
+ ret[k] = cls.child_object_type.to_scheme_keys(v, root_cls, path)
1321
1254
  return ret
1322
1255
  else:
1323
1256
  return value
@@ -1331,7 +1264,7 @@ class NamedObject(SettingsBase[DictStateType], Generic[ChildTypeT]):
1331
1264
  ret[k] = cls.child_object_type.to_python_keys(v)
1332
1265
  return ret
1333
1266
  else:
1334
- return value
1267
+ return {}
1335
1268
 
1336
1269
  _child_classes = {}
1337
1270
  command_names = []
@@ -1464,6 +1397,7 @@ class NamedObject(SettingsBase[DictStateType], Generic[ChildTypeT]):
1464
1397
  def __getattr__(self, name: str):
1465
1398
  alias = self._child_aliases.get(name)
1466
1399
  if alias:
1400
+ alias = alias[0]
1467
1401
  alias_obj = self._child_alias_objs.get(name)
1468
1402
  if alias_obj is None:
1469
1403
  obj = self.find_object(alias)
@@ -1523,10 +1457,12 @@ class ListObject(SettingsBase[ListStateType], Generic[ChildTypeT]):
1523
1457
  self._setattr(query, _create_child(cls, None, self))
1524
1458
 
1525
1459
  @classmethod
1526
- def to_scheme_keys(cls, value):
1460
+ def to_scheme_keys(cls, value, root_cls, path: list[str]):
1527
1461
  """Convert value to have keys with scheme names."""
1528
1462
  if isinstance(value, collections.abc.Sequence):
1529
- return [cls.child_object_type.to_scheme_keys(v) for v in value]
1463
+ return [
1464
+ cls.child_object_type.to_scheme_keys(v, root_cls, path) for v in value
1465
+ ]
1530
1466
  else:
1531
1467
  return value
1532
1468
 
@@ -1536,7 +1472,7 @@ class ListObject(SettingsBase[ListStateType], Generic[ChildTypeT]):
1536
1472
  if isinstance(value, collections.abc.Sequence):
1537
1473
  return [cls.child_object_type.to_python_keys(v) for v in value]
1538
1474
  else:
1539
- return value
1475
+ return []
1540
1476
 
1541
1477
  _child_classes = {}
1542
1478
  command_names = []
@@ -1581,6 +1517,7 @@ class ListObject(SettingsBase[ListStateType], Generic[ChildTypeT]):
1581
1517
  def __getattr__(self, name: str):
1582
1518
  alias = self._child_aliases.get(name)
1583
1519
  if alias:
1520
+ alias = alias[0]
1584
1521
  alias_obj = self._child_alias_objs.get(name)
1585
1522
  if alias_obj is None:
1586
1523
  obj = self.find_object(alias)
@@ -1598,24 +1535,35 @@ class Map(SettingsBase[DictStateType]):
1598
1535
 
1599
1536
  def _get_new_keywords(obj, *args, **kwds):
1600
1537
  newkwds = {}
1601
- argNames = []
1602
- argumentNames = []
1538
+ unknown_keywords = set()
1539
+ # Convert positional arguments to keyword arguments
1603
1540
  if args:
1604
1541
  argNames = obj.argument_names[:]
1605
- for i, arg in enumerate(args):
1606
- ccls = getattr(obj, argNames[0])
1607
- newkwds[ccls.fluent_name] = ccls.to_scheme_keys(arg)
1608
- argNames.pop(0)
1542
+ for arg in args:
1543
+ argName = argNames.pop(0)
1544
+ newkwds[argName] = arg
1609
1545
  if kwds:
1610
- argumentNames = obj.argument_names[:]
1611
- if argNames:
1612
- argumentNames = argNames
1613
- for k, v in kwds.items():
1614
- if k in argumentNames:
1615
- ccls = getattr(obj, k)
1616
- newkwds[ccls.fluent_name] = ccls.to_scheme_keys(v)
1617
- else:
1618
- raise RuntimeError("Argument '" + str(k) + "' is invalid")
1546
+ # Convert deprecated keywords through aliases
1547
+ # We don't get arguments-aliases from static-info yet.
1548
+ argument_aliases_scm = obj.get_attr("arguments-aliases") or {}
1549
+ argument_aliases = {}
1550
+ for k, v in argument_aliases_scm.items():
1551
+ argument_aliases[to_python_name(k)] = to_python_name(v.removeprefix("'"))
1552
+ for k, v in kwds.items():
1553
+ alias = argument_aliases.get(k)
1554
+ if alias:
1555
+ newkwds[alias] = v
1556
+ elif k in obj.argument_names:
1557
+ newkwds[k] = v
1558
+ else:
1559
+ unknown_keywords.add(k)
1560
+ for k in unknown_keywords:
1561
+ # Noisily ignore unknown keywords
1562
+ warnings.warn(
1563
+ f"Unknown keyword '{k}' for command '{obj.python_path}'. "
1564
+ "It will be ignored.",
1565
+ PyFluentUserWarning,
1566
+ )
1619
1567
  return newkwds
1620
1568
 
1621
1569
 
@@ -1660,6 +1608,7 @@ class Action(Base):
1660
1608
  def __getattr__(self, name: str):
1661
1609
  alias = self._child_aliases.get(name)
1662
1610
  if alias:
1611
+ alias = alias[0]
1663
1612
  alias_obj = self._child_alias_objs.get(name)
1664
1613
  if alias_obj is None:
1665
1614
  obj = self.find_object(alias)
@@ -1676,10 +1625,9 @@ class BaseCommand(Action):
1676
1625
 
1677
1626
  def _execute_command(self, *args, **kwds):
1678
1627
  """Execute a command with the specified positional and keyword arguments."""
1679
- newkwds = _get_new_keywords(self, *args, **kwds)
1680
1628
  if self.flproxy.is_interactive_mode():
1681
1629
  prompt = self.flproxy.get_command_confirmation_prompt(
1682
- self._parent.path, self.obj_name, **newkwds
1630
+ self._parent.path, self.obj_name, **kwds
1683
1631
  )
1684
1632
  if prompt:
1685
1633
  valid_responses = {"y": True, "yes": True, "n": False, "no": False}
@@ -1692,7 +1640,7 @@ class BaseCommand(Action):
1692
1640
  else:
1693
1641
  print("Please enter 'y[es]' or 'n[o]'.")
1694
1642
  with self._while_executing_command():
1695
- ret = self.flproxy.execute_cmd(self._parent.path, self.obj_name, **newkwds)
1643
+ ret = self.flproxy.execute_cmd(self._parent.path, self.obj_name, **kwds)
1696
1644
  if os.getenv("PYFLUENT_NO_FIX_PARAMETER_LIST_RETURN") != "1":
1697
1645
  if (self._parent.path, self.obj_name) in [
1698
1646
  ("parameters/input-parameters", "list"),
@@ -1703,15 +1651,24 @@ class BaseCommand(Action):
1703
1651
 
1704
1652
  def execute_command(self, *args, **kwds):
1705
1653
  """Execute command."""
1654
+ kwds = _get_new_keywords(self, *args, **kwds)
1655
+ scmKwds = {}
1706
1656
  for arg, value in kwds.items():
1707
1657
  argument = getattr(self, arg)
1708
- kwds[arg] = argument.before_execute(
1658
+ # Convert path-like values for possible file transfer
1659
+ value = argument.before_execute(
1709
1660
  command_name=self.python_name, value=value, kwargs=kwds
1710
1661
  )
1711
- ret = self._execute_command(*args, **kwds)
1662
+ # Convert key-value to Scheme key-value
1663
+ scmKwds[argument.fluent_name] = argument.to_scheme_keys(
1664
+ value,
1665
+ argument._root.__class__,
1666
+ _get_python_path_comps(argument),
1667
+ )
1668
+ ret = self._execute_command(*args, **scmKwds)
1712
1669
  for arg, value in kwds.items():
1713
1670
  argument = getattr(self, arg)
1714
- kwds[arg] = argument.after_execute(
1671
+ argument.after_execute(
1715
1672
  command_name=self.python_name, value=value, kwargs=kwds
1716
1673
  )
1717
1674
  if (
@@ -1735,15 +1692,18 @@ class BaseCommand(Action):
1735
1692
  raise KeyboardInterrupt
1736
1693
 
1737
1694
 
1738
- # TODO: Remove this after paremater list() method is fixed from Fluent side
1695
+ # TODO: Remove this after parameter list() method is fixed from Fluent side
1739
1696
  def _fix_parameter_list_return(val):
1740
1697
  if isinstance(val, dict):
1741
1698
  new_val = {}
1742
1699
  for name, v in val.items():
1743
1700
  value, units = v
1744
- if len(units) > 0:
1701
+ if len(units) > 0 and isinstance(units[0], str):
1702
+ # Symbols are not stripped in the command return in PyConsole.
1703
+ # Following code will work in both PyConsole and PyFluent.
1704
+ unit = units[0].lstrip("'")
1745
1705
  unit_labels = _fix_parameter_list_return.scheme_eval(
1746
- f"(units/inquire-available-label-strings-for-quantity '{units[0]})"
1706
+ f"(units/inquire-available-label-strings-for-quantity '{unit})"
1747
1707
  )
1748
1708
  unit_label = unit_labels[0] if len(unit_labels) > 0 else ""
1749
1709
  else:
@@ -1785,8 +1745,17 @@ class Query(Action):
1785
1745
 
1786
1746
  def __call__(self, **kwds):
1787
1747
  """Call a query with the specified keyword arguments."""
1788
- newkwds = _get_new_keywords(self, **kwds)
1789
- return self.flproxy.execute_query(self._parent.path, self.obj_name, **newkwds)
1748
+ kwds = _get_new_keywords(self, **kwds)
1749
+ scmKwds = {}
1750
+ for arg, value in kwds.items():
1751
+ argument = getattr(self, arg)
1752
+ # Convert key-value to Scheme key-value
1753
+ scmKwds[argument.fluent_name] = argument.to_scheme_keys(
1754
+ value,
1755
+ argument._root.__class__,
1756
+ _get_python_path_comps(argument),
1757
+ )
1758
+ return self.flproxy.execute_query(self._parent.path, self.obj_name, **scmKwds)
1790
1759
 
1791
1760
 
1792
1761
  _baseTypes = {
@@ -1870,12 +1839,12 @@ class _ChildNamedObjectAccessorMixin(collections.abc.MutableMapping):
1870
1839
 
1871
1840
  def __len__(self):
1872
1841
  """Number of child named objects."""
1873
- l = 0
1842
+ count = 0
1874
1843
  for cname in self.child_names:
1875
1844
  cobj = getattr(self, cname)
1876
1845
  if isinstance(cobj, NamedObject):
1877
- l += len(cobj)
1878
- return l
1846
+ count += len(cobj)
1847
+ return count
1879
1848
 
1880
1849
 
1881
1850
  class CreatableNamedObjectMixin(collections.abc.MutableMapping, Generic[ChildTypeT]):
@@ -2089,6 +2058,7 @@ def get_cls(name, info, parent=None, version=None, parent_taboo=None):
2089
2058
  commands = info.get("commands")
2090
2059
  if commands:
2091
2060
  commands.pop("exit", None)
2061
+ commands.pop("switch-to-meshing-mode", None)
2092
2062
  if commands and not user_creatable:
2093
2063
  commands.pop("create", None)
2094
2064
  if commands:
@@ -2127,12 +2097,22 @@ def get_cls(name, info, parent=None, version=None, parent_taboo=None):
2127
2097
  child_aliases = info.get("child-aliases") or info.get("child_aliases", {})
2128
2098
  command_aliases = info.get("command-aliases") or info.get("command_aliases", {})
2129
2099
  query_aliases = info.get("query-aliases") or info.get("query_aliases", {})
2130
- if child_aliases or command_aliases or query_aliases:
2100
+ argument_aliases = info.get("arguments-aliases") or info.get(
2101
+ "arguments_aliases", {}
2102
+ )
2103
+ if child_aliases or command_aliases or query_aliases or argument_aliases:
2131
2104
  cls._child_aliases = {}
2132
2105
  # No need to differentiate in the Python implementation
2133
- for k, v in (child_aliases | command_aliases | query_aliases).items():
2134
- cls._child_aliases[to_python_name(k)] = "/".join(
2135
- x if x == ".." else to_python_name(x) for x in v.split("/")
2106
+ for k, v in (
2107
+ child_aliases | command_aliases | query_aliases | argument_aliases
2108
+ ).items():
2109
+ # Storing the original name as we don't have any other way
2110
+ # to recover it at runtime.
2111
+ cls._child_aliases[to_python_name(k)] = (
2112
+ "/".join(
2113
+ x if x == ".." else to_python_name(x) for x in v.split("/")
2114
+ ),
2115
+ k,
2136
2116
  )
2137
2117
 
2138
2118
  except Exception:
@@ -2172,53 +2152,45 @@ def get_root(
2172
2152
  version : str
2173
2153
  Fluent version.
2174
2154
 
2155
+ Returns
2156
+ -------
2157
+ root object
2158
+
2175
2159
  Raises
2176
2160
  ------
2177
2161
  RuntimeError
2178
2162
  If hash values are inconsistent.
2179
-
2180
- Returns
2181
- -------
2182
- root object
2183
2163
  """
2184
2164
  from ansys.fluent.core import CODEGEN_OUTDIR, CODEGEN_ZIP_SETTINGS, utils
2185
2165
 
2186
- obj_info = flproxy.get_static_info()
2187
- try:
2188
- if os.getenv("PYFLUENT_USE_OLD_SETTINGSGEN") != "1":
2166
+ if os.getenv("PYFLUENT_USE_OLD_SETTINGSGEN") != "1":
2167
+ try:
2189
2168
  settings = utils.load_module(
2190
2169
  f"settings_{version}",
2191
2170
  CODEGEN_OUTDIR / "solver" / f"settings_{version}.py",
2192
2171
  )
2172
+ root_cls = settings.root
2173
+ except FileNotFoundError:
2174
+ obj_info = flproxy.get_static_info()
2175
+ root_cls, _ = get_cls("", obj_info, version=version)
2176
+ else:
2177
+ if CODEGEN_ZIP_SETTINGS:
2178
+ importer = zipimporter(
2179
+ str(CODEGEN_OUTDIR / "solver" / f"settings_{version}.zip")
2180
+ )
2181
+ settings = importer.load_module("settings")
2193
2182
  else:
2194
- if CODEGEN_ZIP_SETTINGS:
2195
- importer = zipimporter(
2196
- str(CODEGEN_OUTDIR / "solver" / f"settings_{version}.zip")
2197
- )
2198
- settings = importer.load_module("settings")
2199
- else:
2200
- settings = utils.load_module(
2201
- f"settings_{version}",
2202
- CODEGEN_OUTDIR / "solver" / f"settings_{version}" / "__init__.py",
2203
- )
2204
-
2205
- if settings.SHASH != _gethash(obj_info):
2206
- settings_logger.warning(
2207
- "Mismatch between generated file and server object "
2208
- "info. Dynamically created settings classes will "
2209
- "be used."
2183
+ settings = utils.load_module(
2184
+ f"settings_{version}",
2185
+ CODEGEN_OUTDIR / "solver" / f"settings_{version}" / "__init__.py",
2210
2186
  )
2211
- raise RuntimeError("Mismatch in hash values")
2212
- cls = settings.root
2213
- except Exception:
2214
- cls, _ = get_cls("", obj_info, version=version)
2215
- root = cls()
2187
+ root_cls = settings.root
2188
+ root = root_cls()
2216
2189
  root.set_flproxy(flproxy)
2217
2190
  root._set_on_interrupt(interrupt)
2218
2191
  root._set_file_transfer_service(file_transfer_service)
2219
2192
  _Alias.scheme_eval = scheme_eval
2220
2193
  _fix_parameter_list_return.scheme_eval = scheme_eval
2221
- root._setattr("_static_info", obj_info)
2222
2194
  root._setattr("_file_transfer_service", file_transfer_service)
2223
2195
  return root
2224
2196