Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion doc/source/user_guide/meshing_workflows.rst
Original file line number Diff line number Diff line change
Expand Up @@ -607,4 +607,29 @@ Switch to solution mode

.. code:: python

solver = meshing.switch_to_solver()
solver = meshing.switch_to_solver()

Sample use of CommandArguments
------------------------------
This simple example shows you how to use the CommandArgument attributes and explicit
attribute access methods in a watertight geometry meshing workflow.
Note: CommandArgument attributes are read-only.

.. code:: python

import ansys.fluent.core as pyfluent
from ansys.fluent.core import examples

import_filename = examples.download_file('mixing_elbow.pmdb', 'pyfluent/mixing_elbow')
meshing = pyfluent.launch_fluent(mode="meshing", precision='double', processor_count=2)
w = meshing.workflow
w.InitializeWorkflow(WorkflowType='Watertight Geometry')

w.task("Import Geometry").CommandArguments()
w.task("Import Geometry").CommandArguments.FileName.is_read_only()
w.task("Import Geometry").CommandArguments.LengthUnit.is_active()
w.task("Import Geometry").CommandArguments.LengthUnit.allowed_values()
w.task("Import Geometry").CommandArguments.LengthUnit.default_value()
w.task("Import Geometry").CommandArguments.LengthUnit()
w.task("Import Geometry").CommandArguments.CadImportOptions.OneZonePer()
w.task("Import Geometry").CommandArguments.CadImportOptions.FeatureAngle.min()
22 changes: 22 additions & 0 deletions doc/source/user_guide/solver_settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,25 @@ Python code for setting the gravitational acceleration.
.. code:: python

solver.tui.define.operating_conditions.gravity('yes','0','-9.81','0')

Sample use of explicit attribute access methods
-----------------------------------------------
This simple example shows how you use the explicit attribute access methods
in a simple solver session.

**Python code**

.. code:: python

import ansys.fluent.core as pyfluent
from ansys.fluent.core import examples

import_filename = examples.download_file("mixing_elbow.msh.h5", "pyfluent/mixing_elbow")
solver = pyfluent.launch_fluent(mode="solver")

solver.setup.models.viscous.is_active()
solver.setup.models.viscous.model.is_read_only()
solver.setup.models.viscous.model.default_value()
solver.setup.models.viscous.model.allowed_values()
solver.setup.models.discrete_phase.tracking.tracking_parameters.max_number_of_steps.min()
solver.setup.models.discrete_phase.tracking.tracking_parameters.max_number_of_steps.max()
3 changes: 2 additions & 1 deletion doc/styles/Vocab/ANSYS/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ pyvista
Pythonic
Slurm
Univa
sbatch
sbatch
CommandArguments
6 changes: 3 additions & 3 deletions src/ansys/fluent/core/meshing/workflow.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ansys.fluent.core.services.datamodel_se import PyCallableStateObject
from ansys.fluent.core.services.datamodel_se import MakeReadOnly, PyCallableStateObject


def _new_command_for_task(task, meshing):
Expand Down Expand Up @@ -55,8 +55,8 @@ def _refreshed_command(self):
task_arg_state = self.Arguments.get_state()
cmd = self._command()
if task_arg_state:
cmd.update_dict(task_arg_state)
return cmd
cmd.set_state(task_arg_state)
return MakeReadOnly(cmd)

def _command(self):
if not self._cmd:
Expand Down
89 changes: 52 additions & 37 deletions src/ansys/fluent/core/services/datamodel_se.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def __call__(self, *args, **kwds) -> Any:
return self.get_state()


class PyReadOnlyStateContainer(PyCallableStateObject):
class PyStateContainer(PyCallableStateObject):
"""Object class using StateEngine based DatamodelService as backend. Use
this class instead of directly calling DatamodelService's method.

Expand All @@ -230,11 +230,15 @@ class PyReadOnlyStateContainer(PyCallableStateObject):
(This method is the same as the get_attrib_value(attrib)
method.)
get_state()
Get the state of the current object. (This method is the
same as the __call__() method.)
Get the state of the current object.
getState()
Get the state of the current object. (This method is the
same as the __call__() method.)
Deprecated camel case alias of get_state.
set_state()
Set the state of the current object.
setState()
Deprecated camel case alias of set_state.
__call__()
Set the state of the current object if state is provided else get its state.
"""

def __init__(self, service: DatamodelService, rules: str, path: Path = None):
Expand All @@ -257,6 +261,17 @@ def get_state(self) -> Any:

getState = get_state

def set_state(self, state: Any = None, **kwargs) -> None:
request = DataModelProtoModule.SetStateRequest()
request.rules = self.rules
request.path = _convert_path_to_se_path(self.path)
_convert_value_to_variant(
kwargs, request.state
) if kwargs else _convert_value_to_variant(state, request.state)
self.service.set_state(request)

setState = set_state

def get_attrib_value(self, attrib: str) -> Any:
"""Get attribute value of the current object.

Expand Down Expand Up @@ -294,24 +309,6 @@ def help(self) -> None:
).common.helpstring
print(help_string)


class PyStateContainer(PyReadOnlyStateContainer):
"""Object class using StateEngine based DatamodelService as backend. Use
this class instead of directly calling DatamodelService's method.

Methods
-------
get_state()
Get the state of the current object. (This method is the
same as the __call__() method.)
getState()
Get the state of the current object. (This method is the
same as the __call__() method.)
"""

def __init__(self, service: DatamodelService, rules: str, path: Path = None):
super().__init__(service, rules, path)

def __call__(self, *args, **kwargs):
if kwargs:
self.set_state(kwargs)
Expand All @@ -322,17 +319,6 @@ def __call__(self, *args, **kwargs):

docstring = None

def set_state(self, state: Any = None, **kwargs) -> None:
request = DataModelProtoModule.SetStateRequest()
request.rules = self.rules
request.path = _convert_path_to_se_path(self.path)
_convert_value_to_variant(
kwargs, request.state
) if kwargs else _convert_value_to_variant(state, request.state)
self.service.set_state(request)

setState = set_state


class PyMenu(PyStateContainer):
"""Object class using StateEngine based DatamodelService as backend. Use
Expand Down Expand Up @@ -723,7 +709,9 @@ def __getattr__(self, attr):

mode = AccessorModes.get_mode(arg.type)
py_class = mode.value[1]
return py_class(self, attr, self.service, self.rules, self.path, arg)
return MakeReadOnly(
py_class(self, attr, self.service, self.rules, self.path, arg)
)

def get_state(self) -> Any:
parent_state = self.parent.get_state()
Expand All @@ -744,7 +732,7 @@ def help(self) -> None:
pass


class PyCommandArguments(PyReadOnlyStateContainer):
class PyCommandArguments(PyStateContainer):
def __init__(
self,
service: DatamodelService,
Expand Down Expand Up @@ -778,7 +766,9 @@ def __getattr__(self, attr):
if arg.name == attr:
mode = AccessorModes.get_mode(arg.type)
py_class = mode.value[1]
return py_class(self, attr, self.service, self.rules, self.path, arg)
return MakeReadOnly(
py_class(self, attr, self.service, self.rules, self.path, arg)
)


class PyTextualCommandArgumentsSubItem(PyCommandArgumentsSubItem, PyTextual):
Expand Down Expand Up @@ -871,6 +861,31 @@ def get_mode(mode: str) -> "AccessorModes":
return AccessorModes.GENERIC


class MakeReadOnly:
"""Removes 'set_state()' attribute to implement read-only behaviour."""

_unwanted_attr = ["set_state", "setState"]

def __init__(self, cmd):
self._cmd = cmd

def __getattr__(self, attr):
if attr in MakeReadOnly._unwanted_attr:
raise AttributeError("Command Arguments are read-only.")
return getattr(self._cmd, attr)

def __dir__(self):
returned_list = sorted(
set(list(self.__dict__.keys()) + dir(type(self)) + dir(self._cmd))
)
for attr in MakeReadOnly._unwanted_attr:
returned_list.remove(attr)
return returned_list

def __call__(self):
return self._cmd()


class PyMenuGeneric(PyMenu):
attrs = ("service", "rules", "path")

Expand Down
45 changes: 42 additions & 3 deletions tests/test_meshing_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,45 @@ def test_accessors_for_argument_sub_items(new_mesh_session):
).CommandArguments.CadImportOptions.FeatureAngle.allowed_values()


@pytest.mark.dev
@pytest.mark.fluent_231
def test_read_only_behaviour_of_command_arguments(new_mesh_session):
session_new = new_mesh_session
w = session_new.workflow
m = session_new.meshing
w.InitializeWorkflow(WorkflowType="Watertight Geometry")

assert "set_state" not in dir(w.task("Import Geometry").CommandArguments)
assert "set_state" not in dir(w.task("Import Geometry").CommandArguments.LengthUnit)

with pytest.raises(AttributeError) as msg:
w.task("Import Geometry").CommandArguments.MeshUnit.set_state("in")
assert msg.value.args[0] == "Command Arguments are read-only."

assert "set_state" in dir(m.ImportGeometry.new())


@pytest.mark.dev
@pytest.mark.fluent_231
def test_sample_use_of_command_arguments(new_mesh_session):
w = new_mesh_session.workflow

w.InitializeWorkflow(WorkflowType="Watertight Geometry")

assert w.task("Import Geometry").CommandArguments.LengthUnit.allowed_values() == [
"m",
"cm",
"mm",
"in",
"ft",
"um",
"nm",
]
assert w.task("Import Geometry").CommandArguments.LengthUnit.default_value() == "mm"
w.TaskObject["Import Geometry"].Arguments = dict(LengthUnit="in")
assert w.task("Import Geometry").CommandArguments.LengthUnit() == "in"


def test_dummy_journal_data_model_methods(new_mesh_session):
session_new = new_mesh_session

Expand All @@ -303,12 +342,12 @@ def test_dummy_journal_data_model_methods(new_mesh_session):
with pytest.raises(AttributeError) as msg:
w.task("Import Geometry").delete_child()
assert msg.value.args[0] == "This method is yet to be implemented in pyfluent."
with pytest.raises(AttributeError):
with pytest.raises(AttributeError) as msg:
w.task("Import Geometry").delete_child_objects()
assert msg.value.args[0] == "This method is yet to be implemented in pyfluent."
with pytest.raises(AttributeError):
with pytest.raises(AttributeError) as msg:
w.task("Import Geometry").delete_all_child_objects()
assert msg.value.args[0] == "This method is yet to be implemented in pyfluent."
with pytest.raises(AttributeError):
with pytest.raises(AttributeError) as msg:
w.task("Import Geometry").fix_state()
assert msg.value.args[0] == "This method is yet to be implemented in pyfluent."