From a699963399aefa51da10f1f90ea501b80c3197c6 Mon Sep 17 00:00:00 2001
From: Mainak Kundu <94432368+mkundu1@users.noreply.github.com>
Date: Tue, 26 Mar 2024 08:11:53 -0400
Subject: [PATCH 1/7] fix: typing stub (#2614)
* fix: typing stubs
* fix: typing stubs
---
src/ansys/fluent/core/session_meshing.pyi | 8 +++-----
src/ansys/fluent/core/session_pure_meshing.py | 2 +-
src/ansys/fluent/core/session_pure_meshing.pyi | 8 +++-----
src/ansys/fluent/core/session_solver.pyi | 5 +----
4 files changed, 8 insertions(+), 15 deletions(-)
diff --git a/src/ansys/fluent/core/session_meshing.pyi b/src/ansys/fluent/core/session_meshing.pyi
index 19ea2ae8eed..4c72c117089 100644
--- a/src/ansys/fluent/core/session_meshing.pyi
+++ b/src/ansys/fluent/core/session_meshing.pyi
@@ -3,12 +3,10 @@ from ansys.fluent.core.datamodel_241.PMFileManagement import (
)
from ansys.fluent.core.datamodel_241.PartManagement import Root as partmanagement_root
from ansys.fluent.core.datamodel_241.meshing import Root as meshing_root
-from ansys.fluent.core.datamodel_241.meshing_utilities import (
- Root as meshing_utilities_root,
-)
from ansys.fluent.core.datamodel_241.preferences import Root as preferences_root
from ansys.fluent.core.datamodel_241.workflow import Root as workflow_root
-from ansys.fluent.core.solver.tui_241 import main_menu
+from ansys.fluent.core.meshing.tui_241 import main_menu
+from ansys.fluent.core.services.meshing_queries import MeshingQueries
class Meshing:
@property
@@ -16,7 +14,7 @@ class Meshing:
@property
def meshing(self) -> meshing_root: ...
@property
- def meshing_utilities(self) -> meshing_utilities_root: ...
+ def meshing_queries(self) -> MeshingQueries: ...
@property
def workflow(self) -> workflow_root: ...
@property
diff --git a/src/ansys/fluent/core/session_pure_meshing.py b/src/ansys/fluent/core/session_pure_meshing.py
index 9988e38017d..4969c496f31 100644
--- a/src/ansys/fluent/core/session_pure_meshing.py
+++ b/src/ansys/fluent/core/session_pure_meshing.py
@@ -81,7 +81,7 @@ def meshing(self):
return self._base_meshing.meshing
@property
- def meshing_queries(self):
+ def meshing_queries(self) -> MeshingQueries:
"""Datamodel root of meshing_queries."""
if self.get_fluent_version() >= FluentVersion.v232:
return MeshingQueries(self.meshing_queries_service)
diff --git a/src/ansys/fluent/core/session_pure_meshing.pyi b/src/ansys/fluent/core/session_pure_meshing.pyi
index 4a3c03e7b08..c9638a5e1bf 100644
--- a/src/ansys/fluent/core/session_pure_meshing.pyi
+++ b/src/ansys/fluent/core/session_pure_meshing.pyi
@@ -3,12 +3,10 @@ from ansys.fluent.core.datamodel_241.PMFileManagement import (
)
from ansys.fluent.core.datamodel_241.PartManagement import Root as partmanagement_root
from ansys.fluent.core.datamodel_241.meshing import Root as meshing_root
-from ansys.fluent.core.datamodel_241.meshing_utilities import (
- Root as meshing_utilities_root,
-)
from ansys.fluent.core.datamodel_241.preferences import Root as preferences_root
from ansys.fluent.core.datamodel_241.workflow import Root as workflow_root
-from ansys.fluent.core.solver.tui_241 import main_menu
+from ansys.fluent.core.meshing.tui_241 import main_menu
+from ansys.fluent.core.services.meshing_queries import MeshingQueries
class PureMeshing:
@property
@@ -16,7 +14,7 @@ class PureMeshing:
@property
def meshing(self) -> meshing_root: ...
@property
- def meshing_utilities(self) -> meshing_utilities_root: ...
+ def meshing_utilities(self) -> MeshingQueries: ...
@property
def workflow(self) -> workflow_root: ...
def watertight(self): ...
diff --git a/src/ansys/fluent/core/session_solver.pyi b/src/ansys/fluent/core/session_solver.pyi
index 014751ec4b4..ea4411d207a 100644
--- a/src/ansys/fluent/core/session_solver.pyi
+++ b/src/ansys/fluent/core/session_solver.pyi
@@ -1,5 +1,4 @@
from ansys.fluent.core.datamodel_241.preferences import Root as preferences_root
-from ansys.fluent.core.datamodel_241.solverworkflow import Root as solverworkflow_root
from ansys.fluent.core.datamodel_241.workflow import Root as workflow_root
from ansys.fluent.core.solver.settings_241.current_parametric_study import (
current_parametric_study,
@@ -7,8 +6,8 @@ from ansys.fluent.core.solver.settings_241.current_parametric_study import (
from ansys.fluent.core.solver.settings_241.file import file
from ansys.fluent.core.solver.settings_241.mesh import mesh
from ansys.fluent.core.solver.settings_241.parallel import parallel
+from ansys.fluent.core.solver.settings_241.parameters import parameters
from ansys.fluent.core.solver.settings_241.parametric_studies import parametric_studies
-from ansys.fluent.core.solver.settings_241.report import report
from ansys.fluent.core.solver.settings_241.results import results
from ansys.fluent.core.solver.settings_241.server import server
from ansys.fluent.core.solver.settings_241.setup import setup
@@ -44,8 +43,6 @@ class Solver:
@property
def results(self) -> results: ...
@property
- def design(self) -> design: ...
- @property
def parametric_studies(self) -> parametric_studies: ...
@property
def current_parametric_study(self) -> current_parametric_study: ...
From fa529fa5dc4862290c4261cb4b92c5d0c59cf2ea Mon Sep 17 00:00:00 2001
From: Harshal Pohekar <106588300+hpohekar@users.noreply.github.com>
Date: Tue, 26 Mar 2024 17:48:42 +0530
Subject: [PATCH 2/7] fix: Fix for Ansys Lab upload/download methods (#2597)
* fix: Fix for Ansys Lab upload/download methods
* user warning.
* user warning method.
* user warning method 1.
* progressbar
* progressbar fix
* Integrate progressbar and improve error handling
* remove test_uploader
* progressbar2 usage
* suggestion
* restore alive_bar
* restore alive_bar 1
* restore alive_bar 2
---
pyproject.toml | 1 +
.../fluent/core/launcher/pim_launcher.py | 4 +-
src/ansys/fluent/core/session.py | 24 ++++++++--
.../core/utils/file_transfer_service.py | 48 ++++++++++++-------
tests/test_uploader.py | 38 ---------------
5 files changed, 54 insertions(+), 61 deletions(-)
delete mode 100644 tests/test_uploader.py
diff --git a/pyproject.toml b/pyproject.toml
index e998ee50a38..e65c26b1f6b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -39,6 +39,7 @@ importlib-metadata = {version = "^7.0.1", python = "<3.9"}
ansys-api-fluent = "^0.3.22"
ansys-platform-instancemanagement = "^1.0"
ansys-units = "^0.3.2"
+alive-progress = "^3.1.5"
beartype = "^0.17"
docker = "^6.1.3"
grpcio = "^1.30.0"
diff --git a/src/ansys/fluent/core/launcher/pim_launcher.py b/src/ansys/fluent/core/launcher/pim_launcher.py
index 26051c8c0a0..50abe6a3346 100644
--- a/src/ansys/fluent/core/launcher/pim_launcher.py
+++ b/src/ansys/fluent/core/launcher/pim_launcher.py
@@ -200,9 +200,7 @@ def __init__(
"'start_watchdog' argument for 'launch_fluent' is currently not supported "
"when starting a remote Fluent PyPIM client."
)
- self.file_transfer_service = (
- file_transfer_service if file_transfer_service else PimFileTransferService()
- )
+ self.file_transfer_service = file_transfer_service
def __call__(self):
logger.info(
diff --git a/src/ansys/fluent/core/session.py b/src/ansys/fluent/core/session.py
index 612cf96abee..737ab32177c 100644
--- a/src/ansys/fluent/core/session.py
+++ b/src/ansys/fluent/core/session.py
@@ -3,7 +3,7 @@
import importlib
import json
import logging
-from typing import Any, Optional
+from typing import Any, Optional, Union
import warnings
from ansys.fluent.core.fluent_connection import FluentConnection
@@ -308,16 +308,31 @@ def force_exit(self) -> None:
data."""
self._fluent_connection.force_exit()
- def upload(self, file_name: str):
+ def _file_transfer_api_warning(self, method_name: str) -> str:
+ """User warning for upload/download methods."""
+ return f"You have directly called the {method_name} method of the session. \
+ Please be advised that for the current version of Fluent, many API methods \
+ automatically handle file uploads and downloads internally. You may not \
+ need to explicitly call {method_name} in most cases. \
+ However, there are exceptions, particularly in PMFileManagement, where complex \
+ file interactions require explicit use of {method_name} method \
+ for relevant files."
+
+ def upload(
+ self, file_name: Union[list[str], str], remote_file_name: Optional[str] = None
+ ):
"""Upload a file to the server.
Parameters
----------
file_name : str
Name of the local file to upload to the server.
+ remote_file_name : str, optional
+ remote file name, by default None
"""
+ warnings.warn(self._file_transfer_api_warning("upload()"), UserWarning)
if self._file_transfer_service:
- return self._file_transfer_service.upload_file(file_name)
+ return self._file_transfer_service.upload(file_name, remote_file_name)
def download(self, file_name: str, local_directory: Optional[str] = "."):
"""Download a file from the server.
@@ -329,8 +344,9 @@ def download(self, file_name: str, local_directory: Optional[str] = "."):
local_directory : str, optional
Local destination directory. The default is the current working directory.
"""
+ warnings.warn(self._file_transfer_api_warning("download()"), UserWarning)
if self._file_transfer_service:
- return self._file_transfer_service.download_file(file_name, local_directory)
+ return self._file_transfer_service.download(file_name, local_directory)
def __enter__(self):
return self
diff --git a/src/ansys/fluent/core/utils/file_transfer_service.py b/src/ansys/fluent/core/utils/file_transfer_service.py
index 66d10989ea6..904ca6f5437 100644
--- a/src/ansys/fluent/core/utils/file_transfer_service.py
+++ b/src/ansys/fluent/core/utils/file_transfer_service.py
@@ -3,6 +3,8 @@
import os
from typing import Any, Callable, Optional, Union # noqa: F401
+from alive_progress import alive_bar
+
import ansys.platform.instancemanagement as pypim
@@ -99,13 +101,17 @@ def upload_file(self, file_name: str, remote_file_name: Optional[str] = None):
else:
raise FileNotFoundError(f"{file_name} does not exist.")
- def upload(self, file_name: Union[list[str], str]):
+ def upload(
+ self, file_name: Union[list[str], str], remote_file_name: Optional[str] = None
+ ):
"""Upload a file to the server.
Parameters
----------
file_name : str
File name
+ remote_file_name : str, optional
+ remote file name, by default None
Raises
------
FileNotFoundError
@@ -113,12 +119,18 @@ def upload(self, file_name: Union[list[str], str]):
"""
files = [file_name] if isinstance(file_name, str) else file_name
if self.is_configured():
- for file in files:
- if os.path.isfile(file):
- if not self.file_service.file_exist(os.path.basename(file)):
- self.upload_file(file_name=file)
- elif not self.file_service.file_exist(os.path.basename(file)):
- raise FileNotFoundError(f"{file} does not exist.")
+ with alive_bar(len(files), title="Uploading...") as bar:
+ for file in files:
+ if os.path.isfile(file):
+ if not self.file_service.file_exist(os.path.basename(file)):
+ self.upload_file(
+ file_name=file, remote_file_name=remote_file_name
+ )
+ bar()
+ else:
+ print(f"\n{file} already uploaded.\n")
+ elif not self.file_service.file_exist(os.path.basename(file)):
+ raise FileNotFoundError(f"{file} does not exist.")
def download_file(self, file_name: str, local_directory: Optional[str] = None):
"""Download a file from the server supported by `PyPIM`.
@@ -146,8 +158,7 @@ def download_file(self, file_name: str, local_directory: Optional[str] = None):
raise FileNotFoundError("Remote file does not exist.")
def download(
- self,
- file_name: Union[list[str], str],
+ self, file_name: Union[list[str], str], local_directory: Optional[str] = "."
):
"""Download a file from the server.
@@ -155,16 +166,21 @@ def download(
----------
file_name : str
File name
+ local_directory : str, optional
+ local directory, by default None
"""
files = [file_name] if isinstance(file_name, str) else file_name
if self.is_configured():
- for file in files:
- if os.path.isfile(file):
- print(f"\nFile already exists. File path:\n{file}\n")
- else:
- self.download_file(
- file_name=os.path.basename(file), local_directory="."
- )
+ with alive_bar(len(files), title="Downloading...") as bar:
+ for file in files:
+ if os.path.isfile(file):
+ print(f"\nFile already exists. File path:\n{file}\n")
+ else:
+ self.download_file(
+ file_name=os.path.basename(file),
+ local_directory=local_directory,
+ )
+ bar()
def __call__(self, pim_instance: Optional[Any] = None):
self.pim_instance = pim_instance
diff --git a/tests/test_uploader.py b/tests/test_uploader.py
deleted file mode 100644
index c6cb8f4d036..00000000000
--- a/tests/test_uploader.py
+++ /dev/null
@@ -1,38 +0,0 @@
-import pytest
-from util.meshing_workflow import new_mesh_session # noqa: F401
-from util.solver_workflow import new_solver_session # noqa: F401
-
-from ansys.fluent.core import examples
-from ansys.fluent.core.utils.file_transfer_service import PyPIMConfigurationError
-
-import_file_name = examples.download_file(
- "mixing_elbow.msh.h5", "pyfluent/mixing_elbow"
-)
-
-
-def test_meshing_session_upload(new_mesh_session):
- session = new_mesh_session
- with pytest.raises(PyPIMConfigurationError) as e_info:
- session.upload(import_file_name)
- session.exit()
-
-
-def test_meshing_session_download(new_mesh_session):
- session = new_mesh_session
- with pytest.raises(PyPIMConfigurationError) as e_info:
- session.download(import_file_name)
- session.exit()
-
-
-def test_solver_session_upload(new_solver_session):
- session = new_solver_session
- with pytest.raises(PyPIMConfigurationError) as e_info:
- session.upload(import_file_name)
- session.exit()
-
-
-def test_solver_session_download(new_solver_session):
- session = new_solver_session
- with pytest.raises(PyPIMConfigurationError) as e_info:
- session.download(import_file_name)
- session.exit()
From 98193023ca6a970433898b95064a35b3ee8d2b32 Mon Sep 17 00:00:00 2001
From: Mainak Kundu <94432368+mkundu1@users.noreply.github.com>
Date: Tue, 26 Mar 2024 19:40:11 -0400
Subject: [PATCH 3/7] fix: processor_count (#2623)
* fix: processor_count
* fix: processor_count
* fix: processor_count
* fix: processor_count
* fix: processor_count
* fix: processor_count
---
.../core/launcher/process_launch_string.py | 4 ++--
tests/test_launcher.py | 21 +++++++++++++++++--
2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/src/ansys/fluent/core/launcher/process_launch_string.py b/src/ansys/fluent/core/launcher/process_launch_string.py
index 6211e7e26ad..a2149cb05b2 100644
--- a/src/ansys/fluent/core/launcher/process_launch_string.py
+++ b/src/ansys/fluent/core/launcher/process_launch_string.py
@@ -53,8 +53,8 @@ def _build_fluent_launch_args_string(**kwargs) -> str:
json_key = json.dumps(argval)
argval = fluent_map[json_key]
launch_args_string += v["fluent_format"].replace("{}", str(argval))
- addArgs = kwargs.get("additional_arguments")
- if addArgs and "-t" not in addArgs and "-cnf=" not in addArgs:
+ addArgs = kwargs["additional_arguments"]
+ if "-t" not in addArgs and "-cnf=" not in addArgs:
parallel_options = build_parallel_options(
load_machines(ncores=kwargs["processor_count"])
)
diff --git a/tests/test_launcher.py b/tests/test_launcher.py
index 5820fa202b2..cccfacc3eff 100644
--- a/tests/test_launcher.py
+++ b/tests/test_launcher.py
@@ -398,15 +398,32 @@ def test_exposure_and_graphics_driver_arguments():
pyfluent.launch_fluent(graphics_driver="x11" if is_windows() else "dx11")
for m in UIMode:
assert (
- _build_fluent_launch_args_string(ui_mode=m).strip() == f"3ddp -{m.value[0]}"
+ _build_fluent_launch_args_string(
+ ui_mode=m, additional_arguments="", processor_count=None
+ ).strip()
+ == f"3ddp -{m.value[0]}"
if m.value[0]
else " 3ddp"
)
for e in (FluentWindowsGraphicsDriver, FluentLinuxGraphicsDriver):
for m in e:
assert (
- _build_fluent_launch_args_string(graphics_driver=m).strip()
+ _build_fluent_launch_args_string(
+ graphics_driver=m, additional_arguments="", processor_count=None
+ ).strip()
== f"3ddp -driver {m.value[0]}"
if m.value[0]
else " 3ddp"
)
+
+
+def test_processor_count():
+ def get_processor_count(solver):
+ return int(solver.rp_vars("parallel/nprocs_string").strip('"'))
+
+ with pyfluent.launch_fluent(processor_count=2) as solver:
+ assert get_processor_count(solver) == 2
+ # The following check is not yet supported for container launch
+ # https://github.com/ansys/pyfluent/issues/2624
+ # with pyfluent.launch_fluent(additional_arguments="-t2") as solver:
+ # assert get_processor_count(solver) == 2
From c0792a05fa9e92ae1ec65177a4908a91b68598e1 Mon Sep 17 00:00:00 2001
From: Prithwish Mukherjee <109645853+prmukherj@users.noreply.github.com>
Date: Wed, 27 Mar 2024 17:44:06 +0530
Subject: [PATCH 4/7] fix: Update nightly test run and add reduction test.
(#2595)
---
tests/test_meshingmode/test_meshing_launch.py | 2 +-
tests/test_pure_mesh_vs_mesh_workflow.py | 4 ++--
tests/test_reduction.py | 16 ++++++++++++++++
3 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/tests/test_meshingmode/test_meshing_launch.py b/tests/test_meshingmode/test_meshing_launch.py
index 11a8c2d778b..6ad8176b988 100644
--- a/tests/test_meshingmode/test_meshing_launch.py
+++ b/tests/test_meshingmode/test_meshing_launch.py
@@ -13,7 +13,7 @@ def test_launch_pure_meshing(load_mixing_elbow_pure_meshing):
file_name = "launch_pure_meshing_journal.py"
pure_meshing_session.journal.start(file_name)
session_dir = dir(pure_meshing_session)
- for attr in ("field_data", "field_info", "meshing", "workflow"):
+ for attr in ("fields", "meshing", "workflow"):
assert attr in session_dir
workflow = pure_meshing_session.workflow
workflow.TaskObject["Import Geometry"].Execute()
diff --git a/tests/test_pure_mesh_vs_mesh_workflow.py b/tests/test_pure_mesh_vs_mesh_workflow.py
index 9477f625d42..40ad3fb0aaf 100644
--- a/tests/test_pure_mesh_vs_mesh_workflow.py
+++ b/tests/test_pure_mesh_vs_mesh_workflow.py
@@ -11,7 +11,7 @@ def test_pure_meshing_mode(load_mixing_elbow_pure_meshing):
# n.b. 'field_data', 'field_info' need to
# be eliminated from meshing sessions
session_dir = dir(pure_meshing_session)
- for attr in ("meshing", "workflow"):
+ for attr in ("fields", "meshing", "workflow"):
assert attr in session_dir
workflow = pure_meshing_session.workflow
workflow_dir = dir(workflow)
@@ -33,7 +33,7 @@ def test_meshing_mode(load_mixing_elbow_meshing):
# n.b. 'field_data', 'field_info' need to
# be eliminated from meshing sessions
session_dir = dir(meshing_session)
- for attr in ("meshing", "workflow"):
+ for attr in ("fields", "meshing", "workflow"):
assert attr in session_dir
assert meshing_session.workflow.InitializeWorkflow(
WorkflowType="Watertight Geometry"
diff --git a/tests/test_reduction.py b/tests/test_reduction.py
index 0c67e6e58b5..5dab108ca81 100644
--- a/tests/test_reduction.py
+++ b/tests/test_reduction.py
@@ -362,3 +362,19 @@ def test_reduction_does_not_modify_case(load_static_mixer_case):
locations=solver.setup.boundary_conditions.velocity_inlet,
)
assert not solver.scheme_eval.scheme_eval("(case-modified?)")
+
+
+@pytest.mark.fluent_version(">=24.2")
+def test_fix_for_invalid_location_inputs(load_static_mixer_case):
+ solver = load_static_mixer_case
+ solver.solution.initialization.hybrid_initialize()
+
+ assert solver.fields.reduction.area(locations=["inlet1"], ctxt=solver)
+
+ with pytest.raises(RuntimeError):
+ assert solver.fields.reduction.area(locations=["inlet-1"], ctxt=solver)
+
+ assert solver.fields.reduction.area(locations=["inlet1"])
+
+ with pytest.raises(RuntimeError):
+ assert solver.fields.reduction.area(locations=["inlet-1"])
From 02e32af1df00f600585370114ec2d3a40bbd9f43 Mon Sep 17 00:00:00 2001
From: Mainak Kundu <94432368+mkundu1@users.noreply.github.com>
Date: Thu, 28 Mar 2024 08:35:49 -0400
Subject: [PATCH 5/7] build: Bump version 0.21.dev0 (#2626)
* build: Bump version 0.21.dev0
* fix: skip some tests
* Fix meshing workflow test.
---------
Co-authored-by: Prithwish Mukherjee
---
pyproject.toml | 2 +-
src/ansys/fluent/core/_version.py | 2 +-
tests/parametric/test_parametric_workflow.py | 31 ++++++++++++++++++++
tests/test_new_meshing_workflow.py | 4 ---
tests/test_settings_api.py | 1 +
5 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index e65c26b1f6b..2271c1cf28d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"
[tool.poetry]
# Check https://python-poetry.org/docs/pyproject/ for all available sections
name = "ansys-fluent-core"
-version = "0.20.dev12"
+version = "0.21.dev0"
description = "PyFluent provides Pythonic access to Ansys Fluent"
license = "MIT"
authors = ["ANSYS, Inc. "]
diff --git a/src/ansys/fluent/core/_version.py b/src/ansys/fluent/core/_version.py
index f4c1c4d1220..0fbcd63d179 100644
--- a/src/ansys/fluent/core/_version.py
+++ b/src/ansys/fluent/core/_version.py
@@ -6,7 +6,7 @@
"""
# major, minor, patch
-version_info = 0, 20, "dev12"
+version_info = 0, 21, "dev0"
# Nice string for the version
__version__ = ".".join(map(str, version_info))
diff --git a/tests/parametric/test_parametric_workflow.py b/tests/parametric/test_parametric_workflow.py
index 773b8aa1b42..17fb2896362 100644
--- a/tests/parametric/test_parametric_workflow.py
+++ b/tests/parametric/test_parametric_workflow.py
@@ -201,3 +201,34 @@ def test_parametric_workflow():
solver_session.file.parametric_project.archive(archive_name=write_archive_name)
assert archive_name.exists()
solver_session.exit()
+
+
+@pytest.mark.fluent_version(">=24.2")
+def test_parameters_list_function(load_static_mixer_settings_only):
+ solver = load_static_mixer_settings_only
+ solver.tui.define.parameters.enable_in_TUI("yes")
+
+ velocity_inlet = solver.tui.define.boundary_conditions.set.velocity_inlet
+ velocity_inlet("inlet1", (), "vmag", "yes", "inlet1_vel", 1, "quit")
+ velocity_inlet("inlet1", (), "temperature", "yes", "inlet1_temp", 300, "quit")
+ velocity_inlet("inlet2", (), "vmag", "yes", "no", "inlet2_vel", 1, "quit")
+ velocity_inlet("inlet2", (), "temperature", "yes", "no", "inlet2_temp", 350, "quit")
+
+ solver.solution.report_definitions.surface["outlet-temp-avg"] = {}
+ outlet_temp_avg = solver.solution.report_definitions.surface["outlet-temp-avg"]
+ outlet_temp_avg.report_type = "surface-areaavg"
+ outlet_temp_avg.field = "temperature"
+ outlet_temp_avg.surface_names = ["outlet"]
+
+ solver.solution.report_definitions.surface["outlet-vel-avg"] = {}
+ outlet_vel_avg = solver.solution.report_definitions.surface["outlet-vel-avg"]
+ outlet_vel_avg.report_type = "surface-areaavg"
+ outlet_vel_avg.field = "velocity-magnitude"
+ outlet_vel_avg.surface_names = ["outlet"]
+
+ create_output_param = solver.tui.define.parameters.output_parameters.create
+ create_output_param("report-definition", "outlet-temp-avg")
+ create_output_param("report-definition", "outlet-vel-avg")
+
+ assert len(solver.parameters.input_parameters.list()) == 4
+ assert len(solver.parameters.output_parameters.list()) == 2
diff --git a/tests/test_new_meshing_workflow.py b/tests/test_new_meshing_workflow.py
index f6494dfd690..6965c013410 100644
--- a/tests/test_new_meshing_workflow.py
+++ b/tests/test_new_meshing_workflow.py
@@ -5,7 +5,6 @@
from ansys.fluent.core import examples
from ansys.fluent.core.meshing.watertight import watertight_workflow
-from ansys.fluent.core.utils.fluent_version import FluentVersion
from tests.test_datamodel_service import disable_datamodel_cache # noqa: F401
@@ -550,11 +549,8 @@ def test_workflow_and_data_model_methods_new_meshing_workflow(new_mesh_session):
"import_body_of_influence_geometry",
"set_up_periodic_boundaries",
"create_local_refinement_regions",
- "load_cad_geometry",
"run_custom_journal",
]
- if meshing.get_fluent_version() < FluentVersion.v242:
- _next_possible_tasks.remove("load_cad_geometry")
assert (
watertight.task("import_geom_wtm").get_next_possible_tasks()
== _next_possible_tasks
diff --git a/tests/test_settings_api.py b/tests/test_settings_api.py
index 90ad3c7b44b..bec8c0cc3d4 100644
--- a/tests/test_settings_api.py
+++ b/tests/test_settings_api.py
@@ -154,6 +154,7 @@ def test_api_upgrade(new_solver_session, capsys):
".file.read_case" in capsys.readouterr().out
+@pytest.mark.skip
@pytest.mark.fluent_version(">=24.2")
def test_deprecated_settings(new_solver_session):
solver = new_solver_session
From 51fc833aec5bf38572be891a95c2a68b47ee0f8c Mon Sep 17 00:00:00 2001
From: Mainak Kundu <94432368+mkundu1@users.noreply.github.com>
Date: Thu, 28 Mar 2024 12:49:03 -0400
Subject: [PATCH 6/7] fix: dict set-state with alias (#2630)
---
src/ansys/fluent/core/solver/flobject.py | 5 +-
tests/test_settings_api.py | 67 ++++++++++++++++--------
2 files changed, 48 insertions(+), 24 deletions(-)
diff --git a/src/ansys/fluent/core/solver/flobject.py b/src/ansys/fluent/core/solver/flobject.py
index 7d8fb195a61..93779000e3f 100644
--- a/src/ansys/fluent/core/solver/flobject.py
+++ b/src/ansys/fluent/core/solver/flobject.py
@@ -661,10 +661,11 @@ def _unalias(cls, value):
)
ret_alias = ret
comps = alias.split("/")
+ aliased_cls = cls
for i, comp in enumerate(comps):
- cls = cls._child_classes[comp]
+ aliased_cls = aliased_cls._child_classes[comp]
if i == len(comps) - 1:
- ret_alias[comp] = cls._unalias(v)
+ ret_alias[comp] = aliased_cls._unalias(v)
else:
ret_alias[comp] = {}
ret_alias = ret_alias[comp]
diff --git a/tests/test_settings_api.py b/tests/test_settings_api.py
index bec8c0cc3d4..8b3baa44db2 100644
--- a/tests/test_settings_api.py
+++ b/tests/test_settings_api.py
@@ -154,7 +154,6 @@ def test_api_upgrade(new_solver_session, capsys):
".file.read_case" in capsys.readouterr().out
-@pytest.mark.skip
@pytest.mark.fluent_version(">=24.2")
def test_deprecated_settings(new_solver_session):
solver = new_solver_session
@@ -189,56 +188,76 @@ def test_deprecated_settings(new_solver_session):
)
assert (
len(
- solver.setup.boundary_conditions.wall["wall-inlet"].thermal.t._child_aliases
+ solver.setup.boundary_conditions.wall[
+ "wall-inlet"
+ ].thermal.temperature._child_aliases
)
> 0
)
assert (
- solver.setup.boundary_conditions.wall["wall-inlet"].thermal.t._child_aliases[
- "constant"
- ]
+ solver.setup.boundary_conditions.wall[
+ "wall-inlet"
+ ].thermal.temperature._child_aliases["constant"]
== "value"
)
with pytest.warns(DeprecatedSettingWarning):
- solver.setup.boundary_conditions.wall["wall-inlet"].thermal.t.constant = 400
+ solver.setup.boundary_conditions.wall[
+ "wall-inlet"
+ ].thermal.temperature.constant = 400
- assert solver.setup.boundary_conditions.wall["wall-inlet"].thermal.t.value() == 400
+ assert (
+ solver.setup.boundary_conditions.wall["wall-inlet"].thermal.temperature.value()
+ == 400
+ )
assert (
len(
- solver.setup.boundary_conditions.wall["wall-inlet"].thermal.t._child_aliases
+ solver.setup.boundary_conditions.wall[
+ "wall-inlet"
+ ].thermal.temperature._child_aliases
)
> 0
)
assert isinstance(
- solver.setup.boundary_conditions.wall["wall-inlet"].thermal.t._child_alias_objs[
- "constant"
- ],
+ solver.setup.boundary_conditions.wall[
+ "wall-inlet"
+ ].thermal.temperature._child_alias_objs["constant"],
_Alias,
)
- solver.setup.boundary_conditions.wall["wall-inlet"].thermal._setattr(
- "_child_aliases", {"temp": "t"}
- )
with pytest.warns(DeprecatedSettingWarning):
- solver.setup.boundary_conditions.wall["wall-inlet"].thermal.temp.value = 410
+ solver.setup.boundary_conditions.wall["wall-inlet"].thermal.t.value = 410
- assert solver.setup.boundary_conditions.wall["wall-inlet"].thermal.t.value() == 410
+ assert (
+ solver.setup.boundary_conditions.wall["wall-inlet"].thermal.temperature.value()
+ == 410
+ )
solver.setup.boundary_conditions._setattr("_child_aliases", {"w": "wall"})
with pytest.warns(DeprecatedSettingWarning):
- solver.setup.boundary_conditions.w["wall-inlet"].thermal.t.value = 420
+ solver.setup.boundary_conditions.w["wall-inlet"].thermal.temperature.value = 420
- assert solver.setup.boundary_conditions.wall["wall-inlet"].thermal.t.value() == 420
+ assert (
+ solver.setup.boundary_conditions.wall["wall-inlet"].thermal.temperature.value()
+ == 420
+ )
solver.setup._setattr("_child_aliases", {"bc": "boundary_conditions"})
with pytest.warns(DeprecatedSettingWarning):
- solver.setup.bc.wall["wall-inlet"].thermal.t.value = 430
+ solver.setup.bc.wall["wall-inlet"].thermal.temperature.value = 430
- assert solver.setup.boundary_conditions.wall["wall-inlet"].thermal.t.value() == 430
+ assert (
+ solver.setup.boundary_conditions.wall["wall-inlet"].thermal.temperature.value()
+ == 430
+ )
with pytest.warns(DeprecatedSettingWarning):
- solver.setup.boundary_conditions.wall["wall-inlet"].thermal.t.constant = 400
+ solver.setup.boundary_conditions.wall[
+ "wall-inlet"
+ ].thermal.temperature.constant = 400
- assert solver.setup.boundary_conditions.wall["wall-inlet"].thermal.t.value() == 400
+ assert (
+ solver.setup.boundary_conditions.wall["wall-inlet"].thermal.temperature.value()
+ == 400
+ )
solver.results._setattr("_child_aliases", {"gr": "graphics"})
with pytest.warns(DeprecatedSettingWarning):
@@ -270,6 +289,10 @@ def test_deprecated_settings(new_solver_session):
solver.setup.cell_zone_conditions.fluid["elbow-fluid"] = {"material": "air"}
+ solver.setup.boundary_conditions.wall["wall-inlet"] = {
+ "thermal": {"q_dot": {"value": 2000000000}, "wall_thickness": {"value": 0.002}}
+ }
+
@pytest.mark.fluent_version(">=24.2")
def test_command_return_type(new_solver_session):
From 80d492e07ad0413b58bf02661e013d81e8000827 Mon Sep 17 00:00:00 2001
From: Prithwish Mukherjee <109645853+prmukherj@users.noreply.github.com>
Date: Thu, 28 Mar 2024 23:14:50 +0530
Subject: [PATCH 7/7] refactor: update enhanced meshing interface (#2606)
* Return solver session only when switch_to_solver is successful.
* Fix add_child_and_update
* Add tests for 2D Meshing workflow.
* Fix _add_child
* Add documentation.
* Update styling.
* Revert changes in switching to solver.
* Refactoring.
* Refactor and update tests.
* Fix test import.
* Bug fixing.
* Fix behaviour of defer_update
* Update src/ansys/fluent/core/workflow.py
Co-authored-by: Mainak Kundu <94432368+mkundu1@users.noreply.github.com>
* Fix for defer_update.
* Fix doc.
* Update fluent version check.
* Update doc/source/user_guide/meshing_workflow/meshing_workflows.rst
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update doc/source/user_guide/meshing_workflow/meshing_workflows.rst
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update doc/source/user_guide/meshing_workflow/meshing_workflows.rst
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update doc style.
* Update doc/source/user_guide/meshing_workflow/meshing_workflows.rst
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update doc/source/user_guide/meshing_workflow/meshing_workflows.rst
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update doc style.
* Update doc/source/user_guide/meshing_workflow/new_meshing_workflows.rst
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update doc/source/user_guide/meshing_workflow/new_meshing_workflows.rst
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update doc/source/user_guide/meshing_workflow/new_meshing_workflows.rst
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update src/ansys/fluent/core/meshing/meshing_workflow.py
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update src/ansys/fluent/core/meshing/meshing_workflow.py
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update src/ansys/fluent/core/meshing/meshing_workflow.py
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update src/ansys/fluent/core/meshing/meshing_workflow.py
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update src/ansys/fluent/core/session_base_meshing.py
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update src/ansys/fluent/core/workflow.py
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
* Update docs.
* Update meshing test.
* Update const. call from Solver.
---------
Co-authored-by: Mainak Kundu <94432368+mkundu1@users.noreply.github.com>
Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
---
.../meshing_workflow/meshing_workflows.rst | 220 +++++++++++++++++-
.../new_meshing_workflows.rst | 160 +++++++++++++
src/ansys/fluent/core/meshing/2d_meshing.py | 25 --
.../fluent/core/meshing/faulttolerant.py | 25 --
.../fluent/core/meshing/meshing_workflow.py | 200 +++++++++-------
.../fluent/core/meshing/topology_based.py | 25 --
src/ansys/fluent/core/meshing/watertight.py | 32 ---
src/ansys/fluent/core/session_base_meshing.py | 25 +-
src/ansys/fluent/core/session_solver.py | 4 +-
src/ansys/fluent/core/workflow.py | 38 ++-
tests/test_meshing_workflow.py | 186 +++++++++++++--
tests/test_new_meshing_workflow.py | 159 ++++++++++++-
12 files changed, 850 insertions(+), 249 deletions(-)
delete mode 100644 src/ansys/fluent/core/meshing/2d_meshing.py
delete mode 100644 src/ansys/fluent/core/meshing/faulttolerant.py
delete mode 100644 src/ansys/fluent/core/meshing/topology_based.py
delete mode 100644 src/ansys/fluent/core/meshing/watertight.py
diff --git a/doc/source/user_guide/meshing_workflow/meshing_workflows.rst b/doc/source/user_guide/meshing_workflow/meshing_workflows.rst
index e9521789aab..e4b4348fd41 100644
--- a/doc/source/user_guide/meshing_workflow/meshing_workflows.rst
+++ b/doc/source/user_guide/meshing_workflow/meshing_workflows.rst
@@ -572,9 +572,223 @@ Switch to solution mode
solver = meshing.switch_to_solver()
-Sample use of CommandArguments
-------------------------------
-This simple example shows you how to use the ``CommandArgument`` attributes and explicit
+
+2D meshing workflow
+-------------------
+Use the **2D** meshing workflow to mesh specific two-dimensional geometries.
+The following example shows how to use the 2D Meshing workflow.
+
+Import geometry
+~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ import ansys.fluent.core as pyfluent
+ from ansys.fluent.core import examples
+
+ import_file_name = examples.download_file('NACA0012.fmd', 'pyfluent/airfoils')
+ meshing = pyfluent.launch_fluent(
+ mode="meshing", precision='double', processor_count=2
+ )
+ meshing.workflow.InitializeWorkflow(WorkflowType="2D Meshing")
+ meshing.workflow.TaskObject["Load CAD Geometry"].Arguments.set_state(
+ {
+ r"FileName": import_file_name,
+ r"LengthUnit": r"mm",
+ r"Refaceting": {
+ r"Refacet": False,
+ },
+ }
+ )
+ meshing.workflow.TaskObject["Load CAD Geometry"].Execute()
+
+Set regions and boundaries
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ meshing.workflow.TaskObject["Update Regions"].Execute()
+ meshing.workflow.TaskObject["Update Boundaries"].Arguments.set_state(
+ {
+ r"SelectionType": r"zone",
+ }
+ )
+ meshing.workflow.TaskObject["Update Boundaries"].Execute()
+
+Define global sizing
+~~~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ meshing.workflow.TaskObject["Define Global Sizing"].Arguments.set_state(
+ {
+ r"CurvatureNormalAngle": 20,
+ r"MaxSize": 2000,
+ r"MinSize": 5,
+ r"SizeFunctions": r"Curvature",
+ }
+ )
+ meshing.workflow.TaskObject["Define Global Sizing"].Execute()
+
+Add body of influence
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ meshing.workflow.TaskObject["Add Local Sizing"].Arguments.set_state(
+ {
+ r"AddChild": r"yes",
+ r"BOIControlName": r"boi_1",
+ r"BOIExecution": r"Body Of Influence",
+ r"BOIFaceLabelList": [r"boi"],
+ r"BOISize": 50,
+ r"BOIZoneorLabel": r"label",
+ r"DrawSizeControl": True,
+ }
+ )
+ meshing.workflow.TaskObject["Add Local Sizing"].AddChildAndUpdate(DeferUpdate=False)
+
+Set edge sizing
+~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ meshing.workflow.TaskObject["Add Local Sizing"].Arguments.set_state(
+ {
+ r"AddChild": r"yes",
+ r"BOIControlName": r"edgesize_1",
+ r"BOIExecution": r"Edge Size",
+ r"BOISize": 5,
+ r"BOIZoneorLabel": r"label",
+ r"DrawSizeControl": True,
+ r"EdgeLabelList": [r"airfoil-te"],
+ }
+ )
+ meshing.workflow.TaskObject["Add Local Sizing"].AddChildAndUpdate(DeferUpdate=False)
+
+Set curvature sizing
+~~~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ meshing.workflow.TaskObject["Add Local Sizing"].Arguments.set_state(
+ {
+ r"AddChild": r"yes",
+ r"BOIControlName": r"curvature_1",
+ r"BOICurvatureNormalAngle": 10,
+ r"BOIExecution": r"Curvature",
+ r"BOIMaxSize": 2,
+ r"BOIMinSize": 1.5,
+ r"BOIScopeTo": r"edges",
+ r"BOIZoneorLabel": r"label",
+ r"DrawSizeControl": True,
+ r"EdgeLabelList": [r"airfoil"],
+ }
+ )
+ meshing.workflow.TaskObject["Add Local Sizing"].AddChildAndUpdate(DeferUpdate=False)
+
+Add boundary layer
+~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ meshing.workflow.TaskObject["Add 2D Boundary Layers"].Arguments.set_state(
+ {
+ r"AddChild": r"yes",
+ r"BLControlName": r"aspect-ratio_1",
+ r"NumberOfLayers": 4,
+ r"OffsetMethodType": r"aspect-ratio",
+ }
+ )
+ meshing.workflow.TaskObject["Add 2D Boundary Layers"].AddChildAndUpdate(
+ DeferUpdate=False
+ )
+
+Generate surface mesh
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Arguments.set_state(
+ {
+ r"Surface2DPreferences": {
+ r"MergeEdgeZonesBasedOnLabels": r"no",
+ r"MergeFaceZonesBasedOnLabels": r"no",
+ r"ShowAdvancedOptions": True,
+ },
+ }
+ )
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Execute()
+
+ meshing.workflow.TaskObject["aspect-ratio_1"].Revert()
+ meshing.workflow.TaskObject["aspect-ratio_1"].Arguments.set_state(
+ {
+ r"AddChild": r"yes",
+ r"BLControlName": r"uniform_1",
+ r"FirstLayerHeight": 2,
+ r"NumberOfLayers": 4,
+ r"OffsetMethodType": r"uniform",
+ }
+ )
+ meshing.workflow.TaskObject["aspect-ratio_1"].Execute()
+
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Arguments.set_state(None)
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Arguments.set_state(
+ {
+ r"Surface2DPreferences": {
+ r"MergeEdgeZonesBasedOnLabels": r"no",
+ r"MergeFaceZonesBasedOnLabels": r"no",
+ r"ShowAdvancedOptions": True,
+ },
+ }
+ )
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Execute()
+
+ meshing.workflow.TaskObject["uniform_1"].Revert()
+ meshing.workflow.TaskObject["uniform_1"].Arguments.set_state(
+ {
+ r"AddChild": r"yes",
+ r"BLControlName": r"smooth-transition_1",
+ r"FirstLayerHeight": 2,
+ r"NumberOfLayers": 7,
+ r"OffsetMethodType": r"smooth-transition",
+ }
+ )
+ meshing.workflow.TaskObject["uniform_1"].Execute()
+
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Arguments.set_state(None)
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Arguments.set_state(
+ {
+ r"Surface2DPreferences": {
+ r"MergeEdgeZonesBasedOnLabels": r"no",
+ r"MergeFaceZonesBasedOnLabels": r"no",
+ r"ShowAdvancedOptions": True,
+ },
+ }
+ )
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Execute()
+
+Export Fluent 2D mesh
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ meshing.workflow.TaskObject["Export Fluent 2D Mesh"].Arguments.set_state(
+ {
+ r"FileName": r"mesh1.msh.h5",
+ }
+ )
+ meshing.workflow.TaskObject["Export Fluent 2D Mesh"].Execute()
+
+Switch to solver mode
+~~~~~~~~~~~~~~~~~~~~~
+
+Switching to solver mode is not allowed in 2D Meshing mode.
+
+
+Sample use of ``CommandArguments``
+----------------------------------
+This simple example shows how to use the ``CommandArgument`` attributes and explicit
attribute access methods in a watertight geometry meshing workflow.
.. Note::
diff --git a/doc/source/user_guide/meshing_workflow/new_meshing_workflows.rst b/doc/source/user_guide/meshing_workflow/new_meshing_workflows.rst
index 00b01bf7d33..6f68f306c4b 100644
--- a/doc/source/user_guide/meshing_workflow/new_meshing_workflows.rst
+++ b/doc/source/user_guide/meshing_workflow/new_meshing_workflows.rst
@@ -453,3 +453,163 @@ Switch to solution mode
.. code:: python
solver = meshing.switch_to_solver()
+
+
+2D meshing workflow
+-------------------
+Use the **2D** meshing workflow to mesh specific two-dimensional geometries.
+The following example shows you how to use the 2D meshing workflow.
+
+Import geometry
+~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ import ansys.fluent.core as pyfluent
+ from ansys.fluent.core import examples
+
+ import_file_name = examples.download_file('NACA0012.fmd', 'pyfluent/airfoils')
+ meshing = pyfluent.launch_fluent(
+ mode="meshing", precision='double', processor_count=2
+ )
+ two_dim_mesh = new_mesh_session.two_dimensional_meshing()
+
+ two_dim_mesh.load_cad_geometry_2d.file_name = import_file_name
+ two_dim_mesh.load_cad_geometry_2d.length_unit = "mm"
+ two_dim_mesh.load_cad_geometry_2d.refaceting.refacet = False
+ two_dim_mesh.load_cad_geometry_2d()
+
+Set regions and boundaries
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ two_dim_mesh.update_regions_2d()
+ two_dim_mesh.update_boundaries_2d.selection_type = "zone"
+ two_dim_mesh.update_boundaries_2d()
+
+Define global sizing
+~~~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ two_dim_mesh.define_global_sizing_2d.curvature_normal_angle = 20
+ two_dim_mesh.define_global_sizing_2d.max_size = 2000.0
+ two_dim_mesh.define_global_sizing_2d.min_size = 5.0
+ two_dim_mesh.define_global_sizing_2d.size_functions = "Curvature"
+ two_dim_mesh.define_global_sizing_2d()
+
+Adding BOI
+~~~~~~~~~~
+
+.. code:: python
+
+ two_dim_mesh.add_local_sizing_2d.add_child = "yes"
+ two_dim_mesh.add_local_sizing_2d.boi_control_name = "boi_1"
+ two_dim_mesh.add_local_sizing_2d.boi_execution = "Body Of Influence"
+ two_dim_mesh.add_local_sizing_2d.boi_face_label_list = ["boi"]
+ two_dim_mesh.add_local_sizing_2d.boi_size = 50.0
+ two_dim_mesh.add_local_sizing_2d.boi_zoneor_label = "label"
+ two_dim_mesh.add_local_sizing_2d.draw_size_control = True
+ two_dim_mesh.add_local_sizing_2d.add_child_and_update(defer_update=False)
+
+Set edge sizing
+~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ two_dim_mesh.add_local_sizing_2d.add_child = "yes"
+ two_dim_mesh.add_local_sizing_2d.boi_control_name = "edgesize_1"
+ two_dim_mesh.add_local_sizing_2d.boi_execution = "Edge Size"
+ two_dim_mesh.add_local_sizing_2d.boi_size = 5.0
+ two_dim_mesh.add_local_sizing_2d.boi_zoneor_label = "label"
+ two_dim_mesh.add_local_sizing_2d.draw_size_control = True
+ two_dim_mesh.add_local_sizing_2d.edge_label_list = ["airfoil-te"]
+ two_dim_mesh.add_local_sizing_2d.add_child_and_update(defer_update=False)
+
+Set curvature sizing
+~~~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ two_dim_mesh.add_local_sizing_2d.add_child = "yes"
+ two_dim_mesh.add_local_sizing_2d.boi_control_name = "curvature_1"
+ two_dim_mesh.add_local_sizing_2d.boi_curvature_normal_angle = 10
+ two_dim_mesh.add_local_sizing_2d.boi_execution = "Curvature"
+ two_dim_mesh.add_local_sizing_2d.boi_max_size = 2
+ two_dim_mesh.add_local_sizing_2d.boi_min_size = 1.5
+ two_dim_mesh.add_local_sizing_2d.boi_scope_to = "edges"
+ two_dim_mesh.add_local_sizing_2d.boi_zoneor_label = "label"
+ two_dim_mesh.add_local_sizing_2d.draw_size_control = True
+ two_dim_mesh.add_local_sizing_2d.edge_label_list = ["airfoil"]
+ two_dim_mesh.add_local_sizing_2d.add_child_and_update(defer_update=False)
+
+Add boundary layer
+~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ two_dim_mesh.add_2d_boundary_layers.add_child = "yes"
+ two_dim_mesh.add_2d_boundary_layers.bl_control_name = "aspect-ratio_1"
+ two_dim_mesh.add_2d_boundary_layers.number_of_layers = 4
+ two_dim_mesh.add_2d_boundary_layers.offset_method_type = "aspect-ratio"
+ two_dim_mesh.add_2d_boundary_layers.add_child_and_update(defer_update=False)
+
+Generate surface mesh
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: python
+
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.merge_edge_zones_based_on_labels = (
+ "no"
+ )
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.merge_face_zones_based_on_labels = (
+ "no"
+ )
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.show_advanced_options = (
+ True
+ )
+ two_dim_mesh.generate_initial_surface_mesh()
+
+ two_dim_mesh.task("aspect-ratio_1").revert()
+ two_dim_mesh.task("aspect-ratio_1").add_child = "yes"
+ two_dim_mesh.task("aspect-ratio_1").bl_control_name = "uniform_1"
+ two_dim_mesh.task("aspect-ratio_1").first_layer_height = 2
+ two_dim_mesh.task("aspect-ratio_1").number_of_layers = 4
+ two_dim_mesh.task("aspect-ratio_1").offset_method_type = "uniform"
+ two_dim_mesh.task("aspect-ratio_1")()
+
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.merge_edge_zones_based_on_labels = (
+ "no"
+ )
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.merge_face_zones_based_on_labels = (
+ "no"
+ )
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.show_advanced_options = (
+ True
+ )
+ two_dim_mesh.generate_initial_surface_mesh()
+
+ two_dim_mesh.task("uniform_1").revert()
+ two_dim_mesh.task("uniform_1").add_child = "yes"
+ two_dim_mesh.task("uniform_1").bl_control_name = "smooth-transition_1"
+ two_dim_mesh.task("uniform_1").first_layer_height = 2
+ two_dim_mesh.task("uniform_1").number_of_layers = 7
+ two_dim_mesh.task("uniform_1").offset_method_type = "smooth-transition"
+ two_dim_mesh.task("uniform_1")()
+
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.merge_edge_zones_based_on_labels = (
+ "no"
+ )
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.merge_face_zones_based_on_labels = (
+ "no"
+ )
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.show_advanced_options = (
+ True
+ )
+ two_dim_mesh.generate_initial_surface_mesh()
+
+Switch to solution mode
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Switching to solver is not allowed in 2D Meshing mode.
diff --git a/src/ansys/fluent/core/meshing/2d_meshing.py b/src/ansys/fluent/core/meshing/2d_meshing.py
deleted file mode 100644
index 58ee04a0545..00000000000
--- a/src/ansys/fluent/core/meshing/2d_meshing.py
+++ /dev/null
@@ -1,25 +0,0 @@
-"""2D Meshing workflow module."""
-
-from typing import Union
-
-from ..session_meshing import Meshing
-from ..session_pure_meshing import PureMeshing
-from .meshing_workflow import TwoDimensionalMeshingWorkflow
-
-
-def two_dim_workflow(
- session: Union[Meshing, PureMeshing]
-) -> TwoDimensionalMeshingWorkflow:
- """Meshing workflow wrapper, initialized as 2D Meshing.
-
- Parameters
- ----------
- session: Union[Meshing, PureMeshing]
- Meshing session object.
-
- Returns
- -------
- TwoDimensionalMeshingWorkflow
- 2D meshing workflow wrapper.
- """
- return session.two_dimensional_meshing()
diff --git a/src/ansys/fluent/core/meshing/faulttolerant.py b/src/ansys/fluent/core/meshing/faulttolerant.py
deleted file mode 100644
index cfbffdc0920..00000000000
--- a/src/ansys/fluent/core/meshing/faulttolerant.py
+++ /dev/null
@@ -1,25 +0,0 @@
-"""Fault-tolerant workflow module."""
-
-from typing import Union
-
-from ..session_meshing import Meshing
-from ..session_pure_meshing import PureMeshing
-from .meshing_workflow import FaultTolerantMeshingWorkflow
-
-
-def fault_tolerant_workflow(
- session: Union[Meshing, PureMeshing]
-) -> FaultTolerantMeshingWorkflow:
- """Meshing workflow wrapper, initialized as fault-tolerant.
-
- Parameters
- ----------
- session: Union[Meshing, PureMeshing]
- Meshing session object.
-
- Returns
- -------
- FaultTolerantMeshingWorkflow
- Fault-tolerant meshing workflow wrapper.
- """
- return session.fault_tolerant()
diff --git a/src/ansys/fluent/core/meshing/meshing_workflow.py b/src/ansys/fluent/core/meshing/meshing_workflow.py
index 9e5a366fe4c..4238b9107c1 100644
--- a/src/ansys/fluent/core/meshing/meshing_workflow.py
+++ b/src/ansys/fluent/core/meshing/meshing_workflow.py
@@ -3,9 +3,11 @@
from __future__ import annotations
+from enum import Enum
from typing import Optional
from ansys.fluent.core.services.datamodel_se import PyMenuGeneric
+from ansys.fluent.core.utils.fluent_version import FluentVersion
from ansys.fluent.core.workflow import ClassicWorkflow, Workflow
@@ -16,6 +18,7 @@ def __init__(
self,
workflow: PyMenuGeneric,
meshing: PyMenuGeneric,
+ fluent_version: FluentVersion,
) -> None:
"""Initialize ClassicMeshingWorkflow.
@@ -25,8 +28,12 @@ def __init__(
Underlying workflow object.
meshing : PyMenuGeneric
Meshing object.
+ fluent_version: FluentVersion
+ Version of Fluent in this session.
"""
- super().__init__(workflow=workflow, command_source=meshing)
+ super().__init__(
+ workflow=workflow, command_source=meshing, fluent_version=fluent_version
+ )
class MeshingWorkflow(Workflow):
@@ -37,6 +44,9 @@ def __init__(
self,
workflow: PyMenuGeneric,
meshing: PyMenuGeneric,
+ name: str,
+ identifier: str,
+ fluent_version: FluentVersion,
) -> None:
"""Initialize MeshingWorkflow.
@@ -45,43 +55,66 @@ def __init__(
workflow : PyMenuGeneric
Underlying workflow object.
meshing : PyMenuGeneric
- The meshing object.
- """
- super().__init__(workflow=workflow, command_source=meshing)
-
-
-class WatertightMeshingWorkflow(MeshingWorkflow):
- """Provides watertight meshing specialization of the workflow wrapper."""
-
- def __init__(self, workflow: PyMenuGeneric, meshing: PyMenuGeneric) -> None:
- """Initialize WatertightMeshingWorkflow.
-
- Parameters
- ----------
- workflow : PyMenuGeneric
- The underlying workflow object.
- meshing : PyMenuGeneric
- The meshing object.
+ Meshing object.
+ name: str
+ Workflow name to initialize it.
+ identifier: str
+ Workflow name to identify it from global settings.
+ fluent_version: FluentVersion
+ Version of Fluent in this session.
"""
- super().__init__(workflow=workflow, meshing=meshing)
+ super().__init__(
+ workflow=workflow, command_source=meshing, fluent_version=fluent_version
+ )
self._meshing = meshing
+ self._name = name
+ self._identifier = identifier
def reinitialize(self) -> None:
- """Initialize a watertight workflow."""
- self._new_workflow(name="Watertight Geometry")
+ """Initialize a workflow."""
+ self._new_workflow(name=self._name)
def __getattribute__(self, item: str):
if (
item != "reinitialize"
and not item.startswith("_")
- and not self._meshing.GlobalSettings.EnableCleanCAD()
+ and not getattr(self._meshing.GlobalSettings, self._identifier)()
):
raise RuntimeError(
- "'Watertight' objects are inaccessible from other workflows."
+ f"'{self._name}' objects are inaccessible from other workflows."
)
return super().__getattribute__(item)
+class WatertightMeshingWorkflow(MeshingWorkflow):
+ """Provides watertight meshing specialization of the workflow wrapper."""
+
+ def __init__(
+ self,
+ workflow: PyMenuGeneric,
+ meshing: PyMenuGeneric,
+ fluent_version: FluentVersion,
+ ) -> None:
+ """Initialize WatertightMeshingWorkflow.
+
+ Parameters
+ ----------
+ workflow : PyMenuGeneric
+ Underlying workflow object.
+ meshing : PyMenuGeneric
+ Meshing object.
+ fluent_version: FluentVersion
+ Version of Fluent in this session.
+ """
+ super().__init__(
+ workflow=workflow,
+ meshing=meshing,
+ name="Watertight Geometry",
+ identifier="EnableCleanCAD",
+ fluent_version=fluent_version,
+ )
+
+
class FaultTolerantMeshingWorkflow(MeshingWorkflow):
"""Provides fault-tolerant meshing specialization of the workflow wrapper."""
@@ -91,40 +124,33 @@ def __init__(
meshing: PyMenuGeneric,
part_management: PyMenuGeneric,
pm_file_management: PyMenuGeneric,
+ fluent_version: FluentVersion,
) -> None:
"""Initialize FaultTolerantMeshingWorkflow.
Parameters
----------
workflow : PyMenuGeneric
- The underlying workflow object.
+ Underlying workflow object.
meshing : PyMenuGeneric
- The meshing object.
+ Meshing object.
part_management : PyMenuGeneric
- The part-management object.
+ Part management object.
pm_file_management : PyMenuGeneric
- The part-management file-management object.
+ File management object in the part management object.
+ fluent_version: FluentVersion
+ Version of Fluent in this session.
"""
- super().__init__(workflow=workflow, meshing=meshing)
- self._meshing = meshing
+ super().__init__(
+ workflow=workflow,
+ meshing=meshing,
+ name="Fault-tolerant Meshing",
+ identifier="EnableComplexMeshing",
+ fluent_version=fluent_version,
+ )
self._part_management = part_management
self._pm_file_management = pm_file_management
- def reinitialize(self):
- """Initialize a fault-tolerant workflow."""
- self._new_workflow("Fault-tolerant Meshing")
-
- def __getattribute__(self, item):
- if (
- item != "reinitialize"
- and not item.startswith("_")
- and not self._meshing.GlobalSettings.EnableComplexMeshing()
- ):
- raise RuntimeError(
- "'Fault-tolerant' objects are inaccessible from other workflows."
- )
- return super().__getattribute__(item)
-
@property
def part_management(self) -> Optional[PyMenuGeneric]:
"""Access part-management in fault-tolerant mode.
@@ -143,7 +169,7 @@ def pm_file_management(self):
Returns
-------
Optional[PyMenuGeneric]
- Part-management file-management object .
+ File management object in the part management object.
"""
return self._pm_file_management
@@ -151,62 +177,66 @@ def pm_file_management(self):
class TwoDimensionalMeshingWorkflow(MeshingWorkflow):
"""Provides 2D meshing specialization of the workflow wrapper."""
- def __init__(self, workflow: PyMenuGeneric, meshing: PyMenuGeneric) -> None:
+ def __init__(
+ self,
+ workflow: PyMenuGeneric,
+ meshing: PyMenuGeneric,
+ fluent_version: FluentVersion,
+ ) -> None:
"""Initialize TwoDimensionalMeshingWorkflow.
Parameters
----------
workflow : PyMenuGeneric
- The underlying workflow object.
+ Underlying workflow object.
meshing : PyMenuGeneric
- The meshing object.
+ Meshing object.
+ fluent_version: FluentVersion
+ Version of Fluent in this session.
"""
- super().__init__(workflow=workflow, meshing=meshing)
- self._meshing = meshing
-
- def reinitialize(self) -> None:
- """Initialize a 2D meshing workflow."""
- self._new_workflow(name="2D Meshing")
-
- def __getattribute__(self, item: str):
- if (
- item != "reinitialize"
- and not item.startswith("_")
- and not self._meshing.GlobalSettings.EnablePrime2dMeshing()
- ):
- raise RuntimeError(
- "'2D Meshing' objects are inaccessible from other workflows."
- )
- return super().__getattribute__(item)
+ super().__init__(
+ workflow=workflow,
+ meshing=meshing,
+ name="2D Meshing",
+ identifier="EnablePrime2dMeshing",
+ fluent_version=fluent_version,
+ )
class TopologyBasedMeshingWorkflow(MeshingWorkflow):
"""Provides topology-based meshing specialization of the workflow wrapper."""
- def __init__(self, workflow: PyMenuGeneric, meshing: PyMenuGeneric) -> None:
+ def __init__(
+ self,
+ workflow: PyMenuGeneric,
+ meshing: PyMenuGeneric,
+ fluent_version: FluentVersion,
+ ) -> None:
"""Initialize TopologyBasedMeshingWorkflow.
Parameters
----------
workflow : PyMenuGeneric
- The underlying workflow object.
+ Underlying workflow object.
meshing : PyMenuGeneric
- The meshing object.
+ Meshing object.
+ fluent_version: FluentVersion
+ Version of Fluent in this session.
"""
- super().__init__(workflow=workflow, meshing=meshing)
- self._meshing = meshing
-
- def reinitialize(self) -> None:
- """Initialize a topology based meshing workflow."""
- self._new_workflow(name="Topology Based Meshing")
-
- def __getattribute__(self, item: str):
- if (
- item != "reinitialize"
- and not item.startswith("_")
- and not self._meshing.GlobalSettings.EnablePrimeMeshing()
- ):
- raise RuntimeError(
- "'Topology Based Meshing' objects are inaccessible from other workflows."
- )
- return super().__getattribute__(item)
+ super().__init__(
+ workflow=workflow,
+ meshing=meshing,
+ name="Topology Based Meshing",
+ identifier="EnablePrimeMeshing",
+ fluent_version=fluent_version,
+ )
+
+
+class WorkflowMode(Enum):
+ """Provides an enum of supported Fluent meshing workflow modes."""
+
+ CLASSIC_MESHING_MODE = ClassicMeshingWorkflow
+ WATERTIGHT_MESHING_MODE = WatertightMeshingWorkflow
+ FAULT_TOLERANT_MESHING_MODE = FaultTolerantMeshingWorkflow
+ TWO_DIMENSIONAL_MESHING_MODE = TwoDimensionalMeshingWorkflow
+ TOPOLOGY_BASED_MESHING_MODE = TopologyBasedMeshingWorkflow
diff --git a/src/ansys/fluent/core/meshing/topology_based.py b/src/ansys/fluent/core/meshing/topology_based.py
deleted file mode 100644
index d8cd1b9e728..00000000000
--- a/src/ansys/fluent/core/meshing/topology_based.py
+++ /dev/null
@@ -1,25 +0,0 @@
-"""2D Meshing workflow module."""
-
-from typing import Union
-
-from ..session_meshing import Meshing
-from ..session_pure_meshing import PureMeshing
-from .meshing_workflow import TopologyBasedMeshingWorkflow
-
-
-def topology_based_workflow(
- session: Union[Meshing, PureMeshing]
-) -> TopologyBasedMeshingWorkflow:
- """Meshing workflow wrapper, initialized as 2D Meshing.
-
- Parameters
- ----------
- session: Union[Meshing, PureMeshing]
- Meshing session object.
-
- Returns
- -------
- TwoDimensionalMeshingWorkflow
- 2D meshing workflow wrapper.
- """
- return session.topology_based()
diff --git a/src/ansys/fluent/core/meshing/watertight.py b/src/ansys/fluent/core/meshing/watertight.py
deleted file mode 100644
index 4728d8faf2d..00000000000
--- a/src/ansys/fluent/core/meshing/watertight.py
+++ /dev/null
@@ -1,32 +0,0 @@
-"""Watertight workflow module."""
-
-from typing import Optional, Union
-
-from ..session_meshing import Meshing
-from ..session_pure_meshing import PureMeshing
-from .meshing_workflow import WatertightMeshingWorkflow
-
-
-def watertight_workflow(
- session: Union[Meshing, PureMeshing], geometry_file_name: Optional[str] = None
-) -> WatertightMeshingWorkflow:
- """Meshing workflow wrapper, initialized as watertight.
-
- Parameters
- ----------
- session: Union[Meshing, PureMeshing]
- Meshing session object.
- geometry_file_name : Optional[str]
- The path of a valid geometry file to import. Can be unset.
-
- Returns
- -------
- WatertightMeshingWorkflow
- Watertight meshing workflow wrapper.
- """
- watertight = session.watertight()
- if geometry_file_name:
- import_geometry = watertight.import_geometry
- import_geometry.file_name = geometry_file_name
- import_geometry()
- return watertight
diff --git a/src/ansys/fluent/core/session_base_meshing.py b/src/ansys/fluent/core/session_base_meshing.py
index 1806a5c6693..a1e7c42c44e 100644
--- a/src/ansys/fluent/core/session_base_meshing.py
+++ b/src/ansys/fluent/core/session_base_meshing.py
@@ -4,13 +4,7 @@
import logging
from ansys.fluent.core.fluent_connection import FluentConnection
-from ansys.fluent.core.meshing.meshing_workflow import (
- ClassicMeshingWorkflow,
- FaultTolerantMeshingWorkflow,
- TopologyBasedMeshingWorkflow,
- TwoDimensionalMeshingWorkflow,
- WatertightMeshingWorkflow,
-)
+from ansys.fluent.core.meshing.meshing_workflow import WorkflowMode
from ansys.fluent.core.services.datamodel_se import PyMenuGeneric
from ansys.fluent.core.services.datamodel_tui import TUIMenu
from ansys.fluent.core.session_shared import _CODEGEN_MSG_DATAMODEL, _CODEGEN_MSG_TUI
@@ -152,9 +146,10 @@ def _workflow_se(self):
def workflow(self):
"""Datamodel root of workflow."""
if not self._old_workflow:
- self._old_workflow = ClassicMeshingWorkflow(
+ self._old_workflow = WorkflowMode.CLASSIC_MESHING_MODE.value(
self._workflow_se,
self.meshing,
+ self.get_fluent_version(),
)
return self._old_workflow
@@ -162,9 +157,10 @@ def workflow(self):
def watertight_workflow(self):
"""Datamodel root of workflow exposed in object-oriented manner."""
if not self._wt_workflow:
- self._wt_workflow = WatertightMeshingWorkflow(
+ self._wt_workflow = WorkflowMode.WATERTIGHT_MESHING_MODE.value(
self._workflow_se,
self.meshing,
+ self.get_fluent_version(),
)
return self._wt_workflow
@@ -172,21 +168,23 @@ def watertight_workflow(self):
def fault_tolerant_workflow(self):
"""Datamodel root of workflow exposed in object-oriented manner."""
if not self._ft_workflow:
- self._ft_workflow = FaultTolerantMeshingWorkflow(
+ self._ft_workflow = WorkflowMode.FAULT_TOLERANT_MESHING_MODE.value(
self._workflow_se,
self.meshing,
self.PartManagement,
self.PMFileManagement,
+ self.get_fluent_version(),
)
return self._ft_workflow
@property
def two_dimensional_meshing_workflow(self):
- """Datamodel root of workflow exposed in object-oriented manner."""
+ """Data model root of the workflow exposed in an object-oriented manner."""
if not self._2dm_workflow:
- self._2dm_workflow = TwoDimensionalMeshingWorkflow(
+ self._2dm_workflow = WorkflowMode.TWO_DIMENSIONAL_MESHING_MODE.value(
self._workflow_se,
self.meshing,
+ self.get_fluent_version(),
)
return self._2dm_workflow
@@ -194,9 +192,10 @@ def two_dimensional_meshing_workflow(self):
def topology_based_meshing_workflow(self):
"""Datamodel root of workflow exposed in object-oriented manner."""
if not self._tb_workflow:
- self._tb_workflow = TopologyBasedMeshingWorkflow(
+ self._tb_workflow = WorkflowMode.TOPOLOGY_BASED_MESHING_MODE.value(
self._workflow_se,
self.meshing,
+ self.get_fluent_version(),
)
return self._tb_workflow
diff --git a/src/ansys/fluent/core/session_solver.py b/src/ansys/fluent/core/session_solver.py
index 3b9181637ed..c0342359ed3 100644
--- a/src/ansys/fluent/core/session_solver.py
+++ b/src/ansys/fluent/core/session_solver.py
@@ -197,7 +197,9 @@ def _workflow_se(self):
def workflow(self):
"""Datamodel root for workflow."""
if not self._workflow:
- self._workflow = ClassicWorkflow(self._workflow_se, Solver)
+ self._workflow = ClassicWorkflow(
+ self._workflow_se, Solver, self.get_fluent_version()
+ )
return self._workflow
@property
diff --git a/src/ansys/fluent/core/workflow.py b/src/ansys/fluent/core/workflow.py
index ab4e15b7eba..a4ef42a6ff9 100644
--- a/src/ansys/fluent/core/workflow.py
+++ b/src/ansys/fluent/core/workflow.py
@@ -16,6 +16,7 @@
PyMenuGeneric,
PySingletonCommandArgumentsSubItem,
)
+from ansys.fluent.core.utils.fluent_version import FluentVersion
def camel_to_snake_case(camel_case_str: str) -> str:
@@ -180,6 +181,7 @@ def __init__(
_task_list=[],
_task_objects={},
_dynamic_interface=command_source._dynamic_interface,
+ _fluent_version=command_source._fluent_version,
)
)
@@ -979,21 +981,33 @@ def _add_child(self, state: Optional[dict] = None) -> None:
state = state or {}
if self._dynamic_interface:
state.update({"add_child": "yes"})
- self.arguments.set_state(state)
+ self.arguments.update_dict(state)
else:
state.update({"AddChild": "yes"})
- self._task.Arguments.set_state(state)
+ self._task.Arguments.update_dict(state)
- def add_child_and_update(self, state=None):
+ def add_child_and_update(self, state=None, defer_update=None):
"""Add a child to this CompoundTask and update.
Parameters
----------
state : Optional[dict]
Optional state.
+ defer_update : bool, default: False
+ Whether to defer the update.
"""
self._add_child(state)
- self._task.AddChildAndUpdate()
+ if self._fluent_version >= FluentVersion.v241:
+ if defer_update is None:
+ defer_update = False
+ self._task.AddChildAndUpdate(DeferUpdate=defer_update)
+ else:
+ if defer_update is not None:
+ warnings.warn(
+ " The 'defer_update()' method is supported in Fluent 2024 R1 and later.",
+ UserWarning,
+ )
+ self._task.AddChildAndUpdate()
return self.last_child()
def last_child(self) -> BaseTask:
@@ -1060,7 +1074,12 @@ class Workflow:
__call__()
"""
- def __init__(self, workflow: PyMenuGeneric, command_source: PyMenuGeneric) -> None:
+ def __init__(
+ self,
+ workflow: PyMenuGeneric,
+ command_source: PyMenuGeneric,
+ fluent_version: FluentVersion,
+ ) -> None:
"""Initialize WorkflowWrapper.
Parameters
@@ -1094,6 +1113,7 @@ def __init__(self, workflow: PyMenuGeneric, command_source: PyMenuGeneric) -> No
"task_object",
"workflow",
}
+ self._fluent_version = fluent_version
def task(self, name: str) -> BaseTask:
"""Get a TaskObject by name, in a ``BaseTask`` wrapper. The wrapper adds extra
@@ -1394,7 +1414,12 @@ class ClassicWorkflow:
__call__()
"""
- def __init__(self, workflow: PyMenuGeneric, command_source: PyMenuGeneric) -> None:
+ def __init__(
+ self,
+ workflow: PyMenuGeneric,
+ command_source: PyMenuGeneric,
+ fluent_version: FluentVersion,
+ ) -> None:
"""Initialize ClassicWorkflow.
Parameters
@@ -1410,6 +1435,7 @@ def __init__(self, workflow: PyMenuGeneric, command_source: PyMenuGeneric) -> No
threading.RLock()
) # TODO: sort out issues with these un-used variables.
self._dynamic_interface = False
+ self._fluent_version = fluent_version
@property
def TaskObject(self) -> TaskContainer:
diff --git a/tests/test_meshing_workflow.py b/tests/test_meshing_workflow.py
index b73cd711f34..cc1dfcba038 100644
--- a/tests/test_meshing_workflow.py
+++ b/tests/test_meshing_workflow.py
@@ -11,7 +11,6 @@
shared_watertight_workflow_session,
)
-from ansys.fluent.core.meshing.faulttolerant import fault_tolerant_workflow
from ansys.fluent.core.utils.fluent_version import FluentVersion
@@ -364,29 +363,6 @@ def test_iterate_meshing_workflow_task_container(new_mesh_session):
assert tasks[0].name() == "Import Geometry"
-@pytest.mark.fluent_version("==23.2")
-@pytest.mark.codegen_required
-def test_fault_tolerant_workflow(exhaust_system_geometry, new_mesh_session):
- fault_tolerant = fault_tolerant_workflow(session=new_mesh_session)
- part_management = fault_tolerant.part_management
- file_name = exhaust_system_geometry
- part_management.LoadFmdFile(FilePath=file_name)
- part_management.MoveCADComponentsToNewObject(
- Paths=[r"/Bottom,1", r"/Left,1", r"/Others,1", r"/Right,1", r"/Top,1"]
- )
- part_management.Node["Object"].Rename(NewName=r"Engine")
- import_cad = fault_tolerant.task("Import CAD and Part Management")
- import_cad.Arguments.setState(
- {
- r"CreateObjectPer": r"Custom",
- r"FMDFileName": file_name,
- r"FileLoaded": r"yes",
- r"ObjectSetting": r"DefaultObjectSetting",
- }
- )
- import_cad()
-
-
@pytest.mark.codegen_required
def test_modified_workflow(new_mesh_session):
meshing = new_mesh_session
@@ -451,3 +427,165 @@ def test_new_workflow_structure(new_mesh_session):
msg.value.args[0]
== "'WatertightMeshingWorkflow' object has no attribute 'TaskObject'"
)
+
+
+@pytest.mark.nightly
+@pytest.mark.codegen_required
+@pytest.mark.fluent_version(">=24.2")
+def test_new_2d_meshing_workflow(new_mesh_session):
+ # Import geometry
+ # import_file_name = examples.download_file(
+ # "mixing_elbow.pmdb", "pyfluent/mixing_elbow"
+ # )
+ import_file_name = r"C:\ANSYSDev\PyFluent_Dev_01\pyfluent\NACA0012.fmd"
+ meshing = new_mesh_session
+ meshing.workflow.InitializeWorkflow(WorkflowType="2D Meshing")
+ meshing.workflow.TaskObject["Load CAD Geometry"].Arguments.set_state(
+ {
+ r"FileName": import_file_name,
+ r"LengthUnit": r"mm",
+ r"Refaceting": {
+ r"Refacet": False,
+ },
+ }
+ )
+ meshing.workflow.TaskObject["Load CAD Geometry"].Execute()
+
+ meshing.workflow.TaskObject["Update Regions"].Execute()
+ meshing.workflow.TaskObject["Update Boundaries"].Arguments.set_state(
+ {
+ r"SelectionType": r"zone",
+ }
+ )
+ meshing.workflow.TaskObject["Update Boundaries"].Execute()
+
+ meshing.workflow.TaskObject["Define Global Sizing"].Arguments.set_state(
+ {
+ r"CurvatureNormalAngle": 20,
+ r"MaxSize": 2000,
+ r"MinSize": 5,
+ r"SizeFunctions": r"Curvature",
+ }
+ )
+ meshing.workflow.TaskObject["Define Global Sizing"].Execute()
+
+ meshing.workflow.TaskObject["Add Local Sizing"].Arguments.set_state(
+ {
+ r"AddChild": r"yes",
+ r"BOIControlName": r"boi_1",
+ r"BOIExecution": r"Body Of Influence",
+ r"BOIFaceLabelList": [r"boi"],
+ r"BOISize": 50,
+ r"BOIZoneorLabel": r"label",
+ r"DrawSizeControl": True,
+ }
+ )
+ meshing.workflow.TaskObject["Add Local Sizing"].AddChildAndUpdate(DeferUpdate=False)
+
+ meshing.workflow.TaskObject["Add Local Sizing"].Arguments.set_state(
+ {
+ r"AddChild": r"yes",
+ r"BOIControlName": r"edgesize_1",
+ r"BOIExecution": r"Edge Size",
+ r"BOISize": 5,
+ r"BOIZoneorLabel": r"label",
+ r"DrawSizeControl": True,
+ r"EdgeLabelList": [r"airfoil-te"],
+ }
+ )
+ meshing.workflow.TaskObject["Add Local Sizing"].AddChildAndUpdate(DeferUpdate=False)
+
+ meshing.workflow.TaskObject["Add Local Sizing"].Arguments.set_state(
+ {
+ r"AddChild": r"yes",
+ r"BOIControlName": r"curvature_1",
+ r"BOICurvatureNormalAngle": 10,
+ r"BOIExecution": r"Curvature",
+ r"BOIMaxSize": 2,
+ r"BOIMinSize": 1.5,
+ r"BOIScopeTo": r"edges",
+ r"BOIZoneorLabel": r"label",
+ r"DrawSizeControl": True,
+ r"EdgeLabelList": [r"airfoil"],
+ }
+ )
+ meshing.workflow.TaskObject["Add Local Sizing"].AddChildAndUpdate(DeferUpdate=False)
+
+ meshing.workflow.TaskObject["Add 2D Boundary Layers"].Arguments.set_state(
+ {
+ r"AddChild": r"yes",
+ r"BLControlName": r"aspect-ratio_1",
+ r"NumberOfLayers": 4,
+ r"OffsetMethodType": r"aspect-ratio",
+ }
+ )
+ meshing.workflow.TaskObject["Add 2D Boundary Layers"].AddChildAndUpdate(
+ DeferUpdate=False
+ )
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Arguments.set_state(
+ {
+ r"Surface2DPreferences": {
+ r"MergeEdgeZonesBasedOnLabels": r"no",
+ r"MergeFaceZonesBasedOnLabels": r"no",
+ r"ShowAdvancedOptions": True,
+ },
+ }
+ )
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Execute()
+
+ meshing.workflow.TaskObject["aspect-ratio_1"].Revert()
+ meshing.workflow.TaskObject["aspect-ratio_1"].Arguments.set_state(
+ {
+ r"AddChild": r"yes",
+ r"BLControlName": r"uniform_1",
+ r"FirstLayerHeight": 2,
+ r"NumberOfLayers": 4,
+ r"OffsetMethodType": r"uniform",
+ }
+ )
+ meshing.workflow.TaskObject["aspect-ratio_1"].Execute()
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Arguments.set_state(None)
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Arguments.set_state(
+ {
+ r"Surface2DPreferences": {
+ r"MergeEdgeZonesBasedOnLabels": r"no",
+ r"MergeFaceZonesBasedOnLabels": r"no",
+ r"ShowAdvancedOptions": True,
+ },
+ }
+ )
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Execute()
+ meshing.workflow.TaskObject["uniform_1"].Revert()
+ meshing.workflow.TaskObject["uniform_1"].Arguments.set_state(
+ {
+ r"AddChild": r"yes",
+ r"BLControlName": r"smooth-transition_1",
+ r"FirstLayerHeight": 2,
+ r"NumberOfLayers": 7,
+ r"OffsetMethodType": r"smooth-transition",
+ }
+ )
+ meshing.workflow.TaskObject["uniform_1"].Execute()
+
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Arguments.set_state(None)
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Arguments.set_state(
+ {
+ r"Surface2DPreferences": {
+ r"MergeEdgeZonesBasedOnLabels": r"no",
+ r"MergeFaceZonesBasedOnLabels": r"no",
+ r"ShowAdvancedOptions": True,
+ },
+ }
+ )
+ meshing.workflow.TaskObject["Generate the Surface Mesh"].Execute()
+
+ meshing.workflow.TaskObject["Export Fluent 2D Mesh"].Arguments.set_state(
+ {
+ r"FileName": r"C:\ANSYSDev\PyFluent_Dev_01\pyfluent\out\case1.msh.h5",
+ }
+ )
+ meshing.workflow.TaskObject["Export Fluent 2D Mesh"].Execute()
+
+ # Switch to solution mode
+ solver = meshing.switch_to_solver()
+ assert not solver
diff --git a/tests/test_new_meshing_workflow.py b/tests/test_new_meshing_workflow.py
index 6965c013410..5ee54f38fea 100644
--- a/tests/test_new_meshing_workflow.py
+++ b/tests/test_new_meshing_workflow.py
@@ -4,7 +4,6 @@
import pytest
from ansys.fluent.core import examples
-from ansys.fluent.core.meshing.watertight import watertight_workflow
from tests.test_datamodel_service import disable_datamodel_cache # noqa: F401
@@ -473,6 +472,123 @@ def test_new_fault_tolerant_workflow(new_mesh_session):
assert solver
+@pytest.mark.nightly
+@pytest.mark.codegen_required
+@pytest.mark.fluent_version(">=24.2")
+def test_new_2d_meshing_workflow(new_mesh_session):
+ # Import geometry
+ import_file_name = examples.download_file("NACA0012.fmd", "pyfluent/airfoils")
+ two_dim_mesh = new_mesh_session.two_dimensional_meshing()
+
+ two_dim_mesh.load_cad_geometry_2d.file_name = import_file_name
+ two_dim_mesh.load_cad_geometry_2d.length_unit = "mm"
+ two_dim_mesh.load_cad_geometry_2d.refaceting.refacet = False
+ two_dim_mesh.load_cad_geometry_2d()
+
+ # Set regions and boundaries
+ two_dim_mesh.update_regions_2d()
+ two_dim_mesh.update_boundaries_2d.selection_type = "zone"
+ two_dim_mesh.update_boundaries_2d()
+
+ # Define global sizing
+ two_dim_mesh.define_global_sizing_2d.curvature_normal_angle = 20
+ two_dim_mesh.define_global_sizing_2d.max_size = 2000.0
+ two_dim_mesh.define_global_sizing_2d.min_size = 5.0
+ two_dim_mesh.define_global_sizing_2d.size_functions = "Curvature"
+ two_dim_mesh.define_global_sizing_2d()
+
+ # Add local sizing
+ two_dim_mesh.add_local_sizing_2d.add_child = "yes"
+ two_dim_mesh.add_local_sizing_2d.boi_control_name = "boi_1"
+ two_dim_mesh.add_local_sizing_2d.boi_execution = "Body Of Influence"
+ two_dim_mesh.add_local_sizing_2d.boi_face_label_list = ["boi"]
+ two_dim_mesh.add_local_sizing_2d.boi_size = 50.0
+ two_dim_mesh.add_local_sizing_2d.boi_zoneor_label = "label"
+ two_dim_mesh.add_local_sizing_2d.draw_size_control = True
+ two_dim_mesh.add_local_sizing_2d.add_child_and_update(defer_update=False)
+
+ two_dim_mesh.add_local_sizing_2d.add_child = "yes"
+ two_dim_mesh.add_local_sizing_2d.boi_control_name = "edgesize_1"
+ two_dim_mesh.add_local_sizing_2d.boi_execution = "Edge Size"
+ two_dim_mesh.add_local_sizing_2d.boi_size = 5.0
+ two_dim_mesh.add_local_sizing_2d.boi_zoneor_label = "label"
+ two_dim_mesh.add_local_sizing_2d.draw_size_control = True
+ two_dim_mesh.add_local_sizing_2d.edge_label_list = ["airfoil-te"]
+ two_dim_mesh.add_local_sizing_2d.add_child_and_update(defer_update=False)
+
+ two_dim_mesh.add_local_sizing_2d.add_child = "yes"
+ two_dim_mesh.add_local_sizing_2d.boi_control_name = "curvature_1"
+ two_dim_mesh.add_local_sizing_2d.boi_curvature_normal_angle = 10
+ two_dim_mesh.add_local_sizing_2d.boi_execution = "Curvature"
+ two_dim_mesh.add_local_sizing_2d.boi_max_size = 2
+ two_dim_mesh.add_local_sizing_2d.boi_min_size = 1.5
+ two_dim_mesh.add_local_sizing_2d.boi_scope_to = "edges"
+ two_dim_mesh.add_local_sizing_2d.boi_zoneor_label = "label"
+ two_dim_mesh.add_local_sizing_2d.draw_size_control = True
+ two_dim_mesh.add_local_sizing_2d.edge_label_list = ["airfoil"]
+ two_dim_mesh.add_local_sizing_2d.add_child_and_update(defer_update=False)
+
+ # Add boundary layer
+ two_dim_mesh.add_2d_boundary_layers.add_child = "yes"
+ two_dim_mesh.add_2d_boundary_layers.bl_control_name = "aspect-ratio_1"
+ two_dim_mesh.add_2d_boundary_layers.number_of_layers = 4
+ two_dim_mesh.add_2d_boundary_layers.offset_method_type = "aspect-ratio"
+ two_dim_mesh.add_2d_boundary_layers.add_child_and_update(defer_update=False)
+
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.merge_edge_zones_based_on_labels = (
+ "no"
+ )
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.merge_face_zones_based_on_labels = (
+ "no"
+ )
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.show_advanced_options = (
+ True
+ )
+ two_dim_mesh.generate_initial_surface_mesh()
+
+ two_dim_mesh.task("aspect-ratio_1").revert()
+ two_dim_mesh.task("aspect-ratio_1").add_child = "yes"
+ two_dim_mesh.task("aspect-ratio_1").bl_control_name = "uniform_1"
+ two_dim_mesh.task("aspect-ratio_1").first_layer_height = 2
+ two_dim_mesh.task("aspect-ratio_1").number_of_layers = 4
+ two_dim_mesh.task("aspect-ratio_1").offset_method_type = "uniform"
+ two_dim_mesh.task("aspect-ratio_1")()
+
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.merge_edge_zones_based_on_labels = (
+ "no"
+ )
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.merge_face_zones_based_on_labels = (
+ "no"
+ )
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.show_advanced_options = (
+ True
+ )
+ two_dim_mesh.generate_initial_surface_mesh()
+
+ two_dim_mesh.task("uniform_1").revert()
+ two_dim_mesh.task("uniform_1").add_child = "yes"
+ two_dim_mesh.task("uniform_1").bl_control_name = "smooth-transition_1"
+ two_dim_mesh.task("uniform_1").first_layer_height = 2
+ two_dim_mesh.task("uniform_1").number_of_layers = 7
+ two_dim_mesh.task("uniform_1").offset_method_type = "smooth-transition"
+ two_dim_mesh.task("uniform_1")()
+
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.merge_edge_zones_based_on_labels = (
+ "no"
+ )
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.merge_face_zones_based_on_labels = (
+ "no"
+ )
+ two_dim_mesh.generate_initial_surface_mesh.surface2_d_preferences.show_advanced_options = (
+ True
+ )
+ two_dim_mesh.generate_initial_surface_mesh()
+
+ # Switch to solution mode
+ solver = new_mesh_session.switch_to_solver()
+ assert solver
+
+
@pytest.mark.codegen_required
@pytest.mark.fluent_version(">=23.2")
def test_updating_state_in_new_meshing_workflow(new_mesh_session):
@@ -565,9 +681,9 @@ def test_workflow_and_data_model_methods_new_meshing_workflow(new_mesh_session):
@pytest.mark.fluent_version(">=23.2")
@pytest.mark.codegen_required
def test_watertight_workflow(mixing_elbow_geometry, new_mesh_session):
- watertight = watertight_workflow(
- geometry_file_name=mixing_elbow_geometry, session=new_mesh_session
- )
+ watertight = new_mesh_session.watertight()
+ watertight.import_geometry.file_name = mixing_elbow_geometry
+ watertight.import_geometry()
add_local_sizing = watertight.add_local_sizing
assert not add_local_sizing.ordered_children()
add_local_sizing._add_child(state={"boi_face_label_list": ["cold-inlet"]})
@@ -583,9 +699,9 @@ def test_watertight_workflow(mixing_elbow_geometry, new_mesh_session):
@pytest.mark.fluent_version(">=23.2")
@pytest.mark.codegen_required
def test_watertight_workflow_children(mixing_elbow_geometry, new_mesh_session):
- watertight = watertight_workflow(
- geometry_file_name=mixing_elbow_geometry, session=new_mesh_session
- )
+ watertight = new_mesh_session.watertight()
+ watertight.import_geometry.file_name = mixing_elbow_geometry
+ watertight.import_geometry()
add_local_sizing = watertight.add_local_sizing
assert not add_local_sizing.ordered_children()
add_local_sizing._add_child(state={"boi_face_label_list": ["cold-inlet"]})
@@ -619,9 +735,9 @@ def test_watertight_workflow_children(mixing_elbow_geometry, new_mesh_session):
@pytest.mark.fluent_version(">=23.2")
@pytest.mark.codegen_required
def test_watertight_workflow_dynamic_interface(mixing_elbow_geometry, new_mesh_session):
- watertight = watertight_workflow(
- geometry_file_name=mixing_elbow_geometry, session=new_mesh_session
- )
+ watertight = new_mesh_session.watertight()
+ watertight.import_geometry.file_name = mixing_elbow_geometry
+ watertight.import_geometry()
create_volume_mesh = watertight.create_volume_mesh
assert create_volume_mesh is not None
watertight.delete_tasks(list_of_tasks=["create_volume_mesh"])
@@ -651,6 +767,29 @@ def test_watertight_workflow_dynamic_interface(mixing_elbow_geometry, new_mesh_s
watertight.create_volume_mesh
+@pytest.mark.fluent_version("==23.2")
+@pytest.mark.codegen_required
+def test_fault_tolerant_workflow(exhaust_system_geometry, new_mesh_session):
+ fault_tolerant = new_mesh_session.fault_tolerant()
+ part_management = fault_tolerant.part_management
+ file_name = exhaust_system_geometry
+ part_management.LoadFmdFile(FilePath=file_name)
+ part_management.MoveCADComponentsToNewObject(
+ Paths=[r"/Bottom,1", r"/Left,1", r"/Others,1", r"/Right,1", r"/Top,1"]
+ )
+ part_management.Node["Object"].Rename(NewName=r"Engine")
+ import_cad = fault_tolerant.task("Import CAD and Part Management")
+ import_cad.Arguments.setState(
+ {
+ r"CreateObjectPer": r"Custom",
+ r"FMDFileName": file_name,
+ r"FileLoaded": r"yes",
+ r"ObjectSetting": r"DefaultObjectSetting",
+ }
+ )
+ import_cad()
+
+
@pytest.mark.fluent_version(">=23.2")
@pytest.mark.codegen_required
def test_extended_wrapper(new_mesh_session, mixing_elbow_geometry):