Skip to content
Draft
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
2 changes: 2 additions & 0 deletions doc/changelog.d/4265.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Fixed `launch_fluent()` ordering so `case_file_name`/`case_data_file_name` are processed before `journal_file_names` when both are provided.
- In lightweight mode, deferred journal replay now completes before the background sync step begins.
1 change: 1 addition & 0 deletions doc/changelog.d/4990.miscellaneous.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Couple of issues in launch fluent
12 changes: 8 additions & 4 deletions src/ansys/fluent/core/launcher/launcher_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,16 @@ def _confirm_watchdog_start(start_watchdog, cleanup_on_exit, fluent_connection):


def _build_journal_argument(
topy: None | bool | str, journal_file_names: None | str | list[str]
topy: None | bool | str,
journal_file_names: None | str | list[str],
include_journal_file_names: bool = True,
) -> str:
"""Build Fluent commandline journal argument."""

def _impl(
topy: None | bool | str, journal_file_names: None | str | list[str]
topy: None | bool | str,
journal_file_names: None | str | list[str],
include_journal_file_names: bool,
) -> str:
if journal_file_names and not isinstance(journal_file_names, (str, list)):
raise TypeError(
Expand All @@ -228,7 +232,7 @@ def _impl(
fluent_jou_arg = ""
if isinstance(journal_file_names, str):
journal_file_names = [journal_file_names]
if journal_file_names:
if journal_file_names and include_journal_file_names:
fluent_jou_arg += "".join(
[f' -i "{journal}"' for journal in journal_file_names]
)
Expand All @@ -239,4 +243,4 @@ def _impl(
fluent_jou_arg += " -topy"
return fluent_jou_arg

return _impl(topy, journal_file_names)
return _impl(topy, journal_file_names, include_journal_file_names)
74 changes: 53 additions & 21 deletions src/ansys/fluent/core/launcher/standalone_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,14 @@ def __init__(
)
if self.argvals["cwd"]:
self._kwargs.update(cwd=self.argvals["cwd"])
self._defer_journal_file_read = bool(
self.argvals["journal_file_names"]
and (self.argvals["case_file_name"] or self.argvals["case_data_file_name"])
)
self._launch_string += _build_journal_argument(
self.argvals["topy"], self.argvals["journal_file_names"]
self.argvals["topy"],
self.argvals["journal_file_names"],
include_journal_file_names=not self._defer_journal_file_read,
)

if is_windows():
Expand Down Expand Up @@ -294,26 +300,7 @@ def __call__(self):
if len(values) == 3:
ip, port, password = values
watchdog.launch(os.getpid(), port, password, ip)
if self.argvals["case_file_name"]:
if FluentMode.is_meshing(self.argvals["mode"]):
session.tui.file.read_case(self.argvals["case_file_name"])
elif self.argvals["lightweight_mode"]:
session.read_case_lightweight(self.argvals["case_file_name"])
else:
session.settings.file.read(
file_type="case",
file_name=self.argvals["case_file_name"],
)
if self.argvals["case_data_file_name"]:
if not FluentMode.is_meshing(self.argvals["mode"]):
session.settings.file.read(
file_type="case-data",
file_name=self.argvals["case_data_file_name"],
)
else:
raise RuntimeError(
"Case and data file cannot be read in meshing mode."
)
self._process_case_data_and_journals(session)

return session
except Exception as ex:
Expand All @@ -323,3 +310,48 @@ def __call__(self):
server_info_file = Path(self._server_info_file_name)
if server_info_file.exists():
server_info_file.unlink()

@staticmethod
def _get_journal_file_names(
journal_file_names: None | str | list[str],
) -> list[str]:
if isinstance(journal_file_names, str):
return [journal_file_names]
return journal_file_names or []

def _read_journals(self, session) -> None:
for journal_file_name in self._get_journal_file_names(
self.argvals["journal_file_names"]
):
session.execute_tui(
f'/file/read-journal "{Path(journal_file_name).as_posix()}"'
)

def _process_case_data_and_journals(self, session) -> None:
lightweight_sync_deferred = False
if self.argvals["case_file_name"]:
if FluentMode.is_meshing(self.argvals["mode"]):
session.tui.file.read_case(self.argvals["case_file_name"])
elif self.argvals["lightweight_mode"]:
session.read_case_lightweight(
self.argvals["case_file_name"],
start_sync=not self._defer_journal_file_read,
)
lightweight_sync_deferred = self._defer_journal_file_read
else:
session.settings.file.read(
file_type="case",
file_name=self.argvals["case_file_name"],
)
if self.argvals["case_data_file_name"]:
if not FluentMode.is_meshing(self.argvals["mode"]):
session.settings.file.read(
file_type="case-data",
file_name=self.argvals["case_data_file_name"],
)
else:
raise RuntimeError("Case and data file cannot be read in meshing mode.")
if self._defer_journal_file_read:
self._read_journals(session)
if lightweight_sync_deferred:
session.start_case_lightweight_sync()
12 changes: 11 additions & 1 deletion src/ansys/fluent/core/session_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,13 +316,21 @@ def _stop_bg_sessions(self):
if thread.is_alive():
thread.join()

def read_case_lightweight(self, file_name: str):
def start_case_lightweight_sync(self):
"""Start pending lightweight background sync sessions."""
for thread in self._bg_session_threads:
if thread.ident is None:
thread.start()

def read_case_lightweight(self, file_name: str, start_sync: bool = True):
"""Read a case file using light IO mode.

Parameters
----------
file_name : str
Case file name
start_sync : bool, optional
Whether to immediately start lightweight background sync.
"""

self.settings.file.read(
Expand All @@ -336,6 +344,8 @@ def read_case_lightweight(self, file_name: str):
target=self._start_bg_session_and_sync, args=(launcher_args,)
)
)
if start_sync:
self.start_case_lightweight_sync()

def get_state(self) -> StateT:
"""Get the state of the object."""
Expand Down
3 changes: 2 additions & 1 deletion src/ansys/fluent/core/session_solver.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class Solver:
def system_coupling(self) -> SystemCoupling: ...
@property
def preferences(self) -> preferences_root: ...
def read_case_lightweight(self, file_name: str): ...
def start_case_lightweight_sync(self): ...
def read_case_lightweight(self, file_name: str, start_sync: bool = True): ...
def read_case(self, file_name: str): ...
def write_case(self, file_name: str): ...
@property
Expand Down
41 changes: 41 additions & 0 deletions tests/test_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
_build_fluent_launch_args_string,
get_fluent_exe_path,
)
from ansys.fluent.core.launcher.standalone_launcher import StandaloneLauncher
from ansys.fluent.core.utils.fluent_version import FluentVersion
import ansys.platform.instancemanagement as pypim

Expand Down Expand Up @@ -474,6 +475,46 @@ def test_build_journal_argument(topy, journal_file_names, result, raises):
assert _build_journal_argument(topy, journal_file_names) == result


def test_build_journal_argument_without_journal_files_but_with_topy():
assert (
_build_journal_argument("a.py", ["a.jou"], include_journal_file_names=False)
== ' -topy="a.py"'
)


def test_lightweight_case_journal_read_is_completed_before_sync_step():
launcher = object.__new__(StandaloneLauncher)
launcher.argvals = {
"case_file_name": "a.cas.h5",
"case_data_file_name": None,
"mode": FluentMode.SOLVER,
"lightweight_mode": True,
"journal_file_names": ["a.jou", "b.jou"],
}
launcher._defer_journal_file_read = True

calls = []

class _DummySession:
def read_case_lightweight(self, file_name, start_sync=True):
calls.append(("read_case_lightweight", file_name, start_sync))

def execute_tui(self, command):
calls.append(("execute_tui", command))

def start_case_lightweight_sync(self):
calls.append(("start_case_lightweight_sync",))

launcher._process_case_data_and_journals(_DummySession())

assert calls == [
("read_case_lightweight", "a.cas.h5", False),
("execute_tui", '/file/read-journal "a.jou"'),
("execute_tui", '/file/read-journal "b.jou"'),
("start_case_lightweight_sync",),
]


def test_show_gui_raises_warning():
with pytest.warns(PyFluentDeprecationWarning):
grpc_kwds = get_grpc_launcher_args_for_gh_runs()
Expand Down
Loading