-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Factory pattern in launch_fluent (#2252)
* Factory pattern in launch_fluent * use match case anf update containet test * update test * remove match * datamodelgen fix * remove line 986 and 987 * Create separate launcher objects * Add docstrings * Update return type * launch to __call__ * redesign * make get_fluent_launcher_mode private * Revert "make get_fluent_launcher_mode private" This reverts commit 7c46a31. * Revert "redesign" This reverts commit d942189. * Revert "launch to __call__" This reverts commit ef8b7d7. * standalone redesign and tests * dry_run * launch_fluent update * _process_invalid_args update * pim launcher redesign * add docstrings * add docstrings 1 * pim and container tests * update call method * separate launchers * manage imports * resolve import issues * launcher_utils * remove watchdog * import update * test fixes * logger update * fix connect_to_fluent bug * update call() remove fluent_launch_mode from launchers * update call() pim * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update src/ansys/fluent/core/launcher/launcher.py Co-authored-by: Sean Pearson <93727996+seanpearsonuk@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * disable hanging test --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Sean Pearson <93727996+seanpearsonuk@users.noreply.github.com>
- Loading branch information
1 parent
53aa027
commit 7922254
Showing
17 changed files
with
1,475 additions
and
778 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
"""Provides a module for launching Fluent in container mode.""" | ||
|
||
import logging | ||
import os | ||
from typing import Any, Dict, Optional, Union | ||
|
||
from ansys.fluent.core.fluent_connection import FluentConnection | ||
from ansys.fluent.core.launcher.fluent_container import ( | ||
configure_container_dict, | ||
start_fluent_container, | ||
) | ||
from ansys.fluent.core.launcher.launcher_utils import ( | ||
FluentMode, | ||
_build_fluent_launch_args_string, | ||
_get_argvals, | ||
_process_invalid_args, | ||
_process_kwargs, | ||
) | ||
import ansys.fluent.core.launcher.watchdog as watchdog | ||
from ansys.fluent.core.utils.file_transfer_service import RemoteFileHandler | ||
|
||
_THIS_DIR = os.path.dirname(__file__) | ||
_OPTIONS_FILE = os.path.join(_THIS_DIR, "fluent_launcher_options.json") | ||
logger = logging.getLogger("pyfluent.launcher") | ||
|
||
|
||
class DockerLauncher: | ||
"""Instantiates Fluent session in container mode.""" | ||
|
||
def __init__( | ||
self, | ||
argvals: Optional[Any] = None, | ||
product_version: Optional[str] = None, | ||
version: Optional[str] = None, | ||
precision: Optional[str] = None, | ||
processor_count: Optional[int] = None, | ||
journal_file_names: Union[None, str, list[str]] = None, | ||
start_timeout: int = 60, | ||
additional_arguments: Optional[str] = "", | ||
env: Optional[Dict[str, Any]] = None, | ||
start_container: Optional[bool] = None, | ||
container_dict: Optional[dict] = None, | ||
dry_run: bool = False, | ||
cleanup_on_exit: bool = True, | ||
start_transcript: bool = True, | ||
show_gui: Optional[bool] = None, | ||
case_file_name: Optional[str] = None, | ||
case_data_file_name: Optional[str] = None, | ||
lightweight_mode: Optional[bool] = None, | ||
mode: Optional[Union[FluentMode, str, None]] = None, | ||
py: Optional[bool] = None, | ||
gpu: Optional[bool] = None, | ||
cwd: Optional[str] = None, | ||
topy: Optional[Union[str, list]] = None, | ||
start_watchdog: Optional[bool] = None, | ||
**kwargs, | ||
): | ||
"""Launch Fluent session in container mode. | ||
Parameters | ||
---------- | ||
product_version : str, optional | ||
Select an installed version of ANSYS. The string must be in a format like | ||
``"23.2.0"`` (for 2023 R2) matching the documented version format in the | ||
FluentVersion class. The default is ``None``, in which case the newest installed | ||
version is used. | ||
version : str, optional | ||
Geometric dimensionality of the Fluent simulation. The default is ``None``, | ||
in which case ``"3d"`` is used. Options are ``"3d"`` and ``"2d"``. | ||
precision : str, optional | ||
Floating point precision. The default is ``None``, in which case ``"double"`` | ||
is used. Options are ``"double"`` and ``"single"``. | ||
processor_count : int, optional | ||
Number of processors. The default is ``None``, in which case ``1`` | ||
processor is used. In job scheduler environments the total number of | ||
allocated cores is clamped to value of ``processor_count``. | ||
journal_file_names : str or list of str, optional | ||
The string path to a Fluent journal file, or a list of such paths. Fluent will execute the | ||
journal(s). The default is ``None``. | ||
start_timeout : int, optional | ||
Maximum allowable time in seconds for connecting to the Fluent | ||
server. The default is ``60``. | ||
additional_arguments : str, optional | ||
Additional arguments to send to Fluent as a string in the same | ||
format they are normally passed to Fluent on the command line. | ||
env : dict[str, str], optional | ||
Mapping to modify environment variables in Fluent. The default | ||
is ``None``. | ||
start_container : bool, optional | ||
Specifies whether to launch a Fluent Docker container image. For more details about containers, see | ||
:mod:`~ansys.fluent.core.launcher.fluent_container`. | ||
container_dict : dict, optional | ||
Dictionary for Fluent Docker container configuration. If specified, | ||
setting ``start_container = True`` as well is redundant. | ||
Will launch Fluent inside a Docker container using the configuration changes specified. | ||
See also :mod:`~ansys.fluent.core.launcher.fluent_container`. | ||
dry_run : bool, optional | ||
Defaults to False. If True, will not launch Fluent, and will instead print configuration information | ||
that would be used as if Fluent was being launched. If dry running a container start, | ||
``launch_fluent()`` will return the configured ``container_dict``. | ||
cleanup_on_exit : bool, optional | ||
Whether to shut down the connected Fluent session when PyFluent is | ||
exited, or the ``exit()`` method is called on the session instance, | ||
or if the session instance becomes unreferenced. The default is ``True``. | ||
start_transcript : bool, optional | ||
Whether to start streaming the Fluent transcript in the client. The | ||
default is ``True``. You can stop and start the streaming of the | ||
Fluent transcript subsequently via the method calls, ``transcript.start()`` | ||
and ``transcript.stop()`` on the session object. | ||
show_gui : bool, optional | ||
Whether to display the Fluent GUI. The default is ``None``, which does not | ||
cause the GUI to be shown. If a value of ``False`` is | ||
not explicitly provided, the GUI will also be shown if | ||
the environment variable ``PYFLUENT_SHOW_SERVER_GUI`` is set to 1. | ||
case_file_name : str, optional | ||
If provided, the case file at ``case_file_name`` is read into the Fluent session. | ||
case_data_file_name : str, optional | ||
If provided, the case and data files at ``case_data_file_name`` are read into the Fluent session. | ||
lightweight_mode : bool, optional | ||
Whether to run in lightweight mode. In lightweight mode, the lightweight settings are read into the | ||
current Fluent solver session. The mesh is read into a background Fluent solver session which will | ||
replace the current Fluent solver session once the mesh read is complete and the lightweight settings | ||
made by the user in the current Fluent solver session have been applied in the background Fluent | ||
solver session. This is all orchestrated by PyFluent and requires no special usage. | ||
This parameter is used only when ``case_file_name`` is provided. The default is ``False``. | ||
mode : str, optional | ||
Launch mode of Fluent to point to a specific session type. | ||
The default value is ``None``. Options are ``"meshing"``, | ||
``"pure-meshing"`` and ``"solver"``. | ||
py : bool, optional | ||
If True, Fluent will run in Python mode. Default is None. | ||
gpu : bool, optional | ||
If True, Fluent will start with GPU Solver. | ||
cwd : str, Optional | ||
Working directory for the Fluent client. | ||
topy : bool or str, optional | ||
A boolean flag to write the equivalent Python journal(s) from the journal(s) passed. | ||
Can optionally take the file name of the new python journal file. | ||
start_watchdog : bool, optional | ||
When ``cleanup_on_exit`` is True, ``start_watchdog`` defaults to True, | ||
which means an independent watchdog process is run to ensure | ||
that any local GUI-less Fluent sessions started by PyFluent are properly closed (or killed if frozen) | ||
when the current Python process ends. | ||
Returns | ||
------- | ||
:obj:`~typing.Union` [:class:`Meshing<ansys.fluent.core.session_meshing.Meshing>`, \ | ||
:class:`~ansys.fluent.core.session_pure_meshing.PureMeshing`, \ | ||
:class:`~ansys.fluent.core.session_solver.Solver`, \ | ||
:class:`~ansys.fluent.core.session_solver_icing.SolverIcing`, dict] | ||
Session object or configuration dictionary if ``dry_run = True``. | ||
Raises | ||
------ | ||
UnexpectedKeywordArgument | ||
If an unexpected keyword argument is provided. | ||
DockerContainerLaunchNotSupported | ||
If a Fluent Docker container launch is not supported. | ||
Notes | ||
----- | ||
Job scheduler environments such as SLURM, LSF, PBS, etc. allocates resources / compute nodes. | ||
The allocated machines and core counts are queried from the scheduler environment and | ||
passed to Fluent. | ||
""" | ||
_process_kwargs(kwargs) | ||
del kwargs | ||
del start_container | ||
argvals = locals().copy() | ||
_process_invalid_args(dry_run, "container", argvals) | ||
args = _get_argvals(argvals, mode) | ||
argvals.update(args) | ||
for arg_name, arg_values in argvals.items(): | ||
setattr(self, arg_name, arg_values) | ||
self.argvals = argvals | ||
|
||
def __call__(self): | ||
args = _build_fluent_launch_args_string(**self.argvals).split() | ||
if self.meshing_mode: | ||
args.append(" -meshing") | ||
|
||
if self.dry_run: | ||
if self.container_dict is None: | ||
setattr(self, "container_dict", {}) | ||
config_dict, *_ = configure_container_dict(args, **self.container_dict) | ||
from pprint import pprint | ||
|
||
print("\nDocker container run configuration:\n") | ||
print("config_dict = ") | ||
if os.getenv("PYFLUENT_HIDE_LOG_SECRETS") != "1": | ||
pprint(config_dict) | ||
else: | ||
config_dict_h = config_dict.copy() | ||
config_dict_h.pop("environment") | ||
pprint(config_dict_h) | ||
del config_dict_h | ||
return config_dict | ||
|
||
port, password = start_fluent_container(args, self.container_dict) | ||
|
||
session = self.new_session( | ||
fluent_connection=FluentConnection( | ||
port=port, | ||
password=password, | ||
cleanup_on_exit=self.cleanup_on_exit, | ||
start_transcript=self.start_transcript, | ||
launcher_args=self.argvals, | ||
inside_container=True, | ||
), | ||
remote_file_handler=RemoteFileHandler(), | ||
) | ||
|
||
if self.start_watchdog is None and self.cleanup_on_exit: | ||
setattr(self, "start_watchdog", True) | ||
if self.start_watchdog: | ||
logger.debug("Launching Watchdog for Fluent container...") | ||
watchdog.launch(os.getpid(), port, password) | ||
|
||
return session |
Oops, something went wrong.