Skip to content

feat: Remote file transfer strategy #4062

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
May 26, 2025
Merged
1 change: 1 addition & 0 deletions doc/changelog.d/4062.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Remote file transfer strategy
73 changes: 73 additions & 0 deletions doc/source/user_guide/session/launching_ansys_fluent.rst
Original file line number Diff line number Diff line change
Expand Up @@ -380,3 +380,76 @@

>>> import ansys.fluent.core as pyfluent
>>> solver = pyfluent.connect_to_fluent(ip="10.18.19.151", port=44383, password="hbsosnni")


Connecting to Fluent on Windows from a Linux or WSL Host
--------------------------------------------------------

This guide describes how to connect to an ANSYS Fluent instance running on a Windows machine from a Linux or WSL host. It also includes steps to enable remote file transfer.

A. **Set Up Fluent and File Transfer Server on Windows**

1. **Launch Fluent**

Open a command prompt and run:

.. code:: console

ANSYS Inc\v252\fluent\ntbin\win64\fluent.exe 3ddp -sifile=server_info.txt
type server_info.txt

Example output:
``10.18.44.179:51344``, ``5scj6c8l``

2. **Retrieve Connection Details**

Get the IP address, port, and password from the `server_info.txt` file.
Example:
- IP: `10.18.44.179`
- Port: `51344`
- Password: `5scj6c8l`

Check failure on line 410 in doc/source/user_guide/session/launching_ansys_fluent.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] doc/source/user_guide/session/launching_ansys_fluent.rst#L410

[Google.Units] Put a nonbreaking space between the number and the unit in '5s'.
Raw output
{"message": "[Google.Units] Put a nonbreaking space between the number and the unit in '5s'.", "location": {"path": "doc/source/user_guide/session/launching_ansys_fluent.rst", "range": {"start": {"line": 410, "column": 17}}}, "severity": "ERROR"}

3. **Set Working Directory**

Change to the Fluent installation directory:

.. code:: console

cd "ANSYS Inc\v252\fluent\ntbin\win64"

4. **Start the File Transfer Server**

Launch the container:

.. code:: console

docker run -p 50000:50000 -v %cd%:/home/container/workdir ghcr.io/ansys/tools-filetransfer:latest

5. **Allow Inbound TCP Connections**

Configure the Windows Firewall:

- Open: **Control Panel > Windows Defender Firewall > Advanced Settings > Inbound Rules**
- Right-click **Inbound Rules**, select **New Rule**
- Choose **Port**, click **Next**
- Keep **TCP** selected
- Enter the ports in **Specific local ports**: `51344, 50000` then click **Next**
- Select **Allow the connection**, click **Next**
- Leave all profiles (Domain, Private, Public) checked, click **Next**
- Name the rule: `Inbound TCP for Fluent`

B. **Connect from Linux or WSL Host**

Run the following Python code to connect to Fluent and transfer files:

.. code:: python

from ansys.fluent.core import connect_to_fluent
from ansys.fluent.core.utils.file_transfer_service import RemoteFileTransferStrategy

file_service = RemoteFileTransferStrategy("10.18.44.179", 50000)
solver = connect_to_fluent(ip="10.18.44.179", port=51344, password="5scj6c8l", file_transfer_service=file_service)

solver.file.read_case(file_name="/home/user_name/mixing_elbow.cas.h5")
solver.file.write_case(file_name="elbow_remote.cas.h5")

4 changes: 4 additions & 0 deletions src/ansys/fluent/core/launcher/launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ def connect_to_fluent(
server_info_file_name: str | None = None,
password: str | None = None,
start_watchdog: bool | None = None,
file_transfer_service: Any | None = None,
) -> Meshing | PureMeshing | Solver | SolverIcing:
"""Connect to an existing Fluent server instance.

Expand Down Expand Up @@ -393,6 +394,8 @@ def connect_to_fluent(
When ``cleanup_on_exit`` is True, ``start_watchdog`` defaults to True,
which means an independent watchdog process is run to ensure
that any local Fluent connections are properly closed (or terminated if frozen) when Python process ends.
file_transfer_service : optional
File transfer service. Uploads/downloads files to/from the server.

Returns
-------
Expand Down Expand Up @@ -424,4 +427,5 @@ def connect_to_fluent(
fluent_connection=fluent_connection,
scheme_eval=fluent_connection._connection_interface.scheme_eval,
start_transcript=start_transcript,
file_transfer_service=file_transfer_service,
)
2 changes: 1 addition & 1 deletion src/ansys/fluent/core/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ def upload(self, file_name: list[str] | str, remote_file_name: str | None = None
if self._file_transfer_service:
return self._file_transfer_service.upload(file_name, remote_file_name)

def download(self, file_name: str, local_directory: str | None = "."):
def download(self, file_name: str, local_directory: str | None = None):
"""Download a file from the server.

Parameters
Expand Down
83 changes: 83 additions & 0 deletions src/ansys/fluent/core/utils/file_transfer_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,89 @@ def download(self, file_name: list[str] | str, local_directory: str | None = Non
)


class RemoteFileTransferStrategy(FileTransferStrategy):
"""Provides a file transfer service based on the `gRPC client <https://filetransfer.tools.docs.pyansys.com/version/stable/>`_
and `gRPC server <https://filetransfer-server.tools.docs.pyansys.com/version/stable/>`_.
"""

def __init__(
self,
server_ip: str | None = None,
server_port: int | None = None,
):
"""Provides the gRPC-based remote file transfer strategy.

Parameters
----------
server_ip: str
IP address of the server.
server_port : int
Port of the server.
"""
import ansys.tools.filetransfer as ft

self.server_ip = server_ip
self.server_port = server_port

self._client = ft.Client.from_server_address(
f"{self.server_ip}:{self.server_port}"
)

def upload(self, file_name: list[str] | str, remote_file_name: str | None = None):
"""Upload a file to the server.

Parameters
----------
file_name : list[str] | str
File name.
remote_file_name : str, optional
Remote file name. The default is ``None``.

Raises
------
FileNotFoundError
If a file does not exist.
"""
files = _get_files(file_name)
for file in files:
if os.path.isfile(file):
self._client.upload_file(
local_filename=file,
remote_filename=(
remote_file_name if remote_file_name else os.path.basename(file)
),
)
else:
raise FileNotFoundError(f"{file} does not exist.")

def download(self, file_name: list[str] | str, local_directory: str | None = None):
"""Download a file from the server.

Parameters
----------
file_name : list[str] | str
File name.
local_directory : str, optional
Local directory. The default is ``None``.
"""
files = _get_files(file_name)
for file in files:
if os.path.isfile(file):
warnings.warn(
f"\nFile already exists. File path:\n{file}\n",
PyFluentUserWarning,
)
else:
self._client.download_file(
remote_filename=os.path.basename(file),
local_filename=(
local_directory
if os.path.isdir(local_directory)
else os.path.basename(file)
),
)


class PimFileTransferService:
"""Provides a file transfer service based on `PyPIM <https://pypim.docs.pyansys.com/version/stable/>`_ and the ``simple_upload_server()`` method.

Expand Down
Loading