Skip to content
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

feat: App utilities gRPC services #3552

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 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
13 changes: 5 additions & 8 deletions src/ansys/fluent/core/codegen/print_fluent_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,20 @@
from ansys.fluent.core.utils.fluent_version import get_version_for_file_name


def print_fluent_version(version: str, scheme_eval):
def print_fluent_version(version: str, app_utilities):
hpohekar marked this conversation as resolved.
Show resolved Hide resolved
"""Write Fluent version information to file."""
version_file = (CODEGEN_OUTDIR / f"fluent_version_{version}.py").resolve()
with open(version_file, "w", encoding="utf8") as f:
f.write(f'FLUENT_VERSION = "{version}"\n')
f.write(f'FLUENT_BUILD_TIME = "{scheme_eval("(inquire-build-time)")}"\n')
f.write(f'FLUENT_BUILD_ID = "{scheme_eval("(inquire-build-id)")}"\n')
f.write(f'FLUENT_REVISION = "{scheme_eval("(inquire-src-vcs-id)")}"\n')
f.write(f'FLUENT_BRANCH = "{scheme_eval("(inquire-src-vcs-branch)")}"\n')
f.write(f'"{app_utilities.get_build_info()}"\n')
hpohekar marked this conversation as resolved.
Show resolved Hide resolved


def generate(version: str, scheme_eval):
def generate(version: str, app_utilities):
"""Write Fluent version information."""
print_fluent_version(version, scheme_eval)
print_fluent_version(version, app_utilities)


if __name__ == "__main__":
solver = launch_fluent()
version = get_version_for_file_name(session=solver)
generate(version, solver.scheme_eval.scheme_eval)
generate(version, solver.app_utilities)
37 changes: 15 additions & 22 deletions src/ansys/fluent/core/fluent_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import ansys.fluent.core as pyfluent
from ansys.fluent.core.services import service_creator
from ansys.fluent.core.services.app_utilities import AppUtilitiesService
from ansys.fluent.core.services.scheme_eval import SchemeEvalService
from ansys.fluent.core.utils.execution import timeout_exec, timeout_loop
from ansys.fluent.core.utils.file_transfer_service import RemoteFileTransferStrategy
Expand Down Expand Up @@ -246,15 +247,17 @@ def __init__(self, create_grpc_service, error_state):
self.scheme_eval = service_creator("scheme_eval").create(
self._scheme_eval_service
)
self._app_utilities_service = create_grpc_service(
AppUtilitiesService, error_state
)
self.app_utilities = service_creator("app_utilities").create(
self._app_utilities_service
)

@property
def product_build_info(self) -> str:
"""Get Fluent build information."""
build_time = self.scheme_eval.scheme_eval("(inquire-build-time)")
build_id = self.scheme_eval.scheme_eval("(inquire-build-id)")
rev = self.scheme_eval.scheme_eval("(inquire-src-vcs-id)")
branch = self.scheme_eval.scheme_eval("(inquire-src-vcs-branch)")
return f"Build Time: {build_time} Build Id: {build_id} Revision: {rev} Branch: {branch}"
self.app_utilities.get_build_info()

def get_cortex_connection_properties(self):
"""Get connection properties of Fluent."""
Expand All @@ -263,10 +266,11 @@ def get_cortex_connection_properties(self):
try:
logger.info(self.product_build_info)
logger.debug("Obtaining Cortex connection properties...")
fluent_host_pid = self.scheme_eval.scheme_eval("(cx-client-id)")
cortex_host = self.scheme_eval.scheme_eval("(cx-cortex-host)")
cortex_pid = self.scheme_eval.scheme_eval("(cx-cortex-id)")
cortex_pwd = self.scheme_eval.scheme_eval("(cortex-pwd)")
cortex_info = self.app_utilities.get_controller_process_info()
fluent_host_pid = self.app_utilities.get_solver_process_info()["process_id"]
cortex_host = cortex_info["hostname"]
cortex_pid = cortex_info["process_id"]
cortex_pwd = cortex_info["working_directory"]
logger.debug("Cortex connection properties successfully obtained.")
except _InactiveRpcError:
logger.warning(
Expand All @@ -282,22 +286,11 @@ def get_cortex_connection_properties(self):

def get_mode(self):
"""Get the mode of a running fluent session."""
from ansys.fluent.core import FluentMode

if self.scheme_eval.scheme_eval("(cx-solver-mode?)"):
mode_str = self.scheme_eval.scheme_eval('(getenv "PRJAPP_APP")')
if mode_str == "flaero_server":
return FluentMode.SOLVER_AERO
elif mode_str == "flicing":
return FluentMode.SOLVER_ICING
else:
return FluentMode.SOLVER
else:
return FluentMode.MESHING
return self.app_utilities.get_app_mode()

def exit_server(self):
"""Exits the server."""
self.scheme_eval.exec(("(exit-server)",))
self.app_utilities.exit()


def _pid_exists(pid):
Expand Down
8 changes: 4 additions & 4 deletions src/ansys/fluent/core/journaling.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
class Journal:
"""Control the writing of Fluent Python journals."""

def __init__(self, scheme_eval):
def __init__(self, app_utilities):
"""__init__ method of Journal class."""
self.scheme_eval = scheme_eval
self.app_utilities = app_utilities

def start(self, file_name: str):
"""Start writing a Fluent Python journal at the specified file_name."""
self.scheme_eval.exec([f'(api-start-python-journal "{file_name}")'])
self.app_utilities.start_python_journal(journal_name=file_name)

def stop(self):
"""Stop writing the Fluent Python journal."""
self.scheme_eval.exec(["(api-stop-python-journal)"])
self.app_utilities.stop_python_journal()
2 changes: 2 additions & 0 deletions src/ansys/fluent/core/services/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Provides a module to create gRPC services."""

from ansys.fluent.core.services.app_utilities import AppUtilities
from ansys.fluent.core.services.batch_ops import BatchOpsService
from ansys.fluent.core.services.datamodel_se import (
DatamodelService as DatamodelService_SE,
Expand All @@ -22,6 +23,7 @@
from ansys.fluent.core.services.transcript import TranscriptService

_service_cls_by_name = {
"app_utilities": AppUtilities,
"health_check": HealthCheckService,
"datamodel": DatamodelService_SE,
"tui": DatamodelService_TUI,
Expand Down
241 changes: 241 additions & 0 deletions src/ansys/fluent/core/services/app_utilities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
"""Wrappers over AppUtilities gRPC service of Fluent."""

from typing import Any, List, Tuple

import grpc

from ansys.api.fluent.v0 import app_utilities_pb2 as AppUtilitiesProtoModule
from ansys.api.fluent.v0 import app_utilities_pb2_grpc as AppUtilitiesGrpcModule
import ansys.fluent.core as pyfluent
Copy link
Collaborator

@seanpearsonuk seanpearsonuk Dec 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hpohekar Please focus your imports to the things that your code needs. We should not see this anywhere inside the code.

from ansys.fluent.core.services.interceptors import (
BatchInterceptor,
ErrorStateInterceptor,
GrpcErrorInterceptor,
TracingInterceptor,
)
from ansys.fluent.core.streaming_services.events_streaming import SolverEvent


class AppUtilitiesService:
"""AppUtilities Service."""

def __init__(
self, channel: grpc.Channel, metadata: List[Tuple[str, str]], fluent_error_state
):
"""__init__ method of AppUtilities class."""
intercept_channel = grpc.intercept_channel(
channel,
GrpcErrorInterceptor(),
ErrorStateInterceptor(fluent_error_state),
TracingInterceptor(),
BatchInterceptor(),
)
self._stub = AppUtilitiesGrpcModule.AppUtilitiesStub(intercept_channel)
self._metadata = metadata

def get_product_version(
self, request: AppUtilitiesProtoModule.GetProductVersionRequest
) -> AppUtilitiesProtoModule.GetProductVersionResponse:
"""Get product version RPC of AppUtilities service."""
return self._stub.GetProductVersion(request, metadata=self._metadata)

def get_build_info(
self, request: AppUtilitiesProtoModule.GetBuildInfoRequest
) -> AppUtilitiesProtoModule.GetBuildInfoResponse:
"""Get build info RPC of AppUtilities service."""
return self._stub.GetBuildInfo(request, metadata=self._metadata)

def get_controller_process_info(
self, request: AppUtilitiesProtoModule.GetControllerProcessInfoRequest
) -> AppUtilitiesProtoModule.GetControllerProcessInfoResponse:
"""Get controller process info RPC of AppUtilities service."""
return self._stub.GetControllerProcessInfo(request, metadata=self._metadata)

def get_solver_process_info(
self, request: AppUtilitiesProtoModule.GetSolverProcessInfoRequest
) -> AppUtilitiesProtoModule.GetSolverProcessInfoResponse:
"""Get solver process info RPC of AppUtilities service."""
return self._stub.GetSolverProcessInfo(request, metadata=self._metadata)

def get_app_mode(
self, request: AppUtilitiesProtoModule.GetAppModeRequest
) -> AppUtilitiesProtoModule.GetAppModeResponse:
"""Get app mode RPC of AppUtilities service."""
return self._stub.GetAppMode(request, metadata=self._metadata)

def start_python_journal(
self, request: AppUtilitiesProtoModule.StartPythonJournalRequest
) -> AppUtilitiesProtoModule.StartPythonJournalResponse:
"""Start python journal RPC of AppUtilities service."""
return self._stub.StartPythonJournal(request, metadata=self._metadata)

def stop_python_journal(
self, request: AppUtilitiesProtoModule.StopPythonJournalRequest
) -> AppUtilitiesProtoModule.StopPythonJournalResponse:
"""Stop python journal RPC of AppUtilities service."""
return self._stub.StopPythonJournal(request, metadata=self._metadata)

def is_beta_enabled(
self, request: AppUtilitiesProtoModule.IsBetaEnabledRequest
) -> AppUtilitiesProtoModule.IsBetaEnabledResponse:
"""Is beta enabled RPC of AppUtilities service."""
return self._stub.IsBetaEnabled(request, metadata=self._metadata)

def is_wildcard(
self, request: AppUtilitiesProtoModule.IsWildcardRequest
) -> AppUtilitiesProtoModule.IsWildcardResponse:
"""Is wildcard RPC of AppUtilities service."""
return self._stub.IsWildcard(request, metadata=self._metadata)

def is_solution_data_available(
self, request: AppUtilitiesProtoModule.IsSolutionDataAvailableRequest
) -> AppUtilitiesProtoModule.IsSolutionDataAvailableResponse:
"""Is solution data available RPC of AppUtilities service."""
return self._stub.IsSolutionDataAvailable(request, metadata=self._metadata)

def register_pause_on_solution_events(
self, request: AppUtilitiesProtoModule.RegisterPauseOnSolutionEventsRequest
) -> AppUtilitiesProtoModule.RegisterPauseOnSolutionEventsResponse:
"""Register on pause solution events RPC of AppUtilities service."""
return self._stub.RegisterPauseOnSolutionEvents(
request, metadata=self._metadata
)

def resume_on_solution_event(
self, request: AppUtilitiesProtoModule.ResumeOnSolutionEventRequest
) -> AppUtilitiesProtoModule.ResumeOnSolutionEventResponse:
"""Resume on solution event RPC of AppUtilities service."""
return self._stub.ResumeOnSolutionEvent(request, metadata=self._metadata)

def unregister_pause_on_solution_events(
self, request: AppUtilitiesProtoModule.UnregisterPauseOnSolutionEventsRequest
) -> AppUtilitiesProtoModule.UnregisterPauseOnSolutionEventsResponse:
"""Unregister on pause solution events RPC of AppUtilities service."""
return self._stub.UnregisterPauseOnSolutionEvents(
request, metadata=self._metadata
)

def exit(
self, request: AppUtilitiesProtoModule.ExitRequest
) -> AppUtilitiesProtoModule.ExitResponse:
"""Exit RPC of AppUtilities service."""
return self._stub.Exit(request, metadata=self._metadata)


class AppUtilities:
hpohekar marked this conversation as resolved.
Show resolved Hide resolved
"""AppUtilities."""

def __init__(self, service: AppUtilitiesService):
"""__init__ method of AppUtilities class."""
self.service = service

def get_product_version(self) -> Any:
"""Get product version."""
request = AppUtilitiesProtoModule.GetProductVersionRequest()
response = self.service.get_product_version(request)
return f"{response.major}.{response.minor}.{response.patch}"

def get_build_info(self) -> Any:
"""Get build info."""
request = AppUtilitiesProtoModule.GetBuildInfoRequest()
response = self.service.get_build_info(request)
return f"Build Time: {response.build_time} Build ID: {response.build_id} Revision: {response.vcs_revision} Branch: {response.vcs_branch}"

def get_controller_process_info(self) -> Any:
"""Get controller process info."""
request = AppUtilitiesProtoModule.GetControllerProcessInfoRequest()
response = self.service.get_controller_process_info(request)
return {
"hostname": response.hostname,
"process_id": response.process_id,
"working_directory": response.working_directory,
}

def get_solver_process_info(self) -> Any:
"""Get solver process info."""
request = AppUtilitiesProtoModule.GetSolverProcessInfoRequest()
response = self.service.get_solver_process_info(request)
hpohekar marked this conversation as resolved.
Show resolved Hide resolved
return {
"hostname": response.hostname,
"process_id": response.process_id,
"working_directory": response.working_directory,
}

def get_app_mode(self) -> Any:
"""Get app mode."""
request = AppUtilitiesProtoModule.GetAppModeRequest()
response = self.service.get_app_mode(request)
if response.app_mode == 0:
return "APP_MODE_UNKNOWN"
hpohekar marked this conversation as resolved.
Show resolved Hide resolved
elif response.app_mode == 1:
hpohekar marked this conversation as resolved.
Show resolved Hide resolved
return pyfluent.FluentMode.MESHING
elif response.app_mode == 2:
return pyfluent.FluentMode.SOLVER
elif response.app_mode == 3:
return pyfluent.FluentMode.SOLVER_ICING
elif response.app_mode == 4:
return pyfluent.FluentMode.SOLVER_AERO

def start_python_journal(self, journal_name: str | None = None) -> Any:
"""Start python journal."""
request = AppUtilitiesProtoModule.StartPythonJournalRequest()
request.journal_name = journal_name
response = self.service.start_python_journal(request)
return response

def stop_python_journal(self) -> Any:
"""Stop python journal."""
request = AppUtilitiesProtoModule.StopPythonJournalRequest()
response = self.service.stop_python_journal(request)
return response
hpohekar marked this conversation as resolved.
Show resolved Hide resolved

def is_beta_enabled(self) -> Any:
"""Is beta enabled."""
request = AppUtilitiesProtoModule.IsBetaEnabledRequest()
response = self.service.is_beta_enabled(request)
return response.is_beta_enabled

def is_wildcard(self, input: str | None = None) -> Any:
"""Is wildcard."""
request = AppUtilitiesProtoModule.IsWildcardRequest()
request.input = input
response = self.service.is_wildcard(request)
return response.is_wildcard

def is_solution_data_available(self) -> Any:
"""Is solution data available."""
request = AppUtilitiesProtoModule.IsSolutionDataAvailableRequest()
response = self.service.is_solution_data_available(request)
return response.is_solution_data_available

def register_pause_on_solution_events(self, solution_event: SolverEvent) -> Any:
"""Register pause on solution events."""
request = AppUtilitiesProtoModule.RegisterPauseOnSolutionEventsRequest()
if solution_event == SolverEvent.TIMESTEP_ENDED:
request.solution_event = 2
elif solution_event == SolverEvent.ITERATION_ENDED:
request.solution_event = 1
else:
request.solution_event = 0
response = self.service.register_pause_on_solution_events(request)
return response.registration_id

def resume_on_solution_event(self, registration_id: str) -> Any:
"""Resume on solution event."""
request = AppUtilitiesProtoModule.ResumeOnSolutionEventRequest()
request.registration_id = registration_id
response = self.service.resume_on_solution_event(request)
return response

def unregister_pause_on_solution_events(self, registration_id: str) -> Any:
"""Unregister pause on solution events."""
request = AppUtilitiesProtoModule.UnregisterPauseOnSolutionEventsRequest()
request.registration_id = registration_id
response = self.service.unregister_pause_on_solution_events(request)
return response

def exit(self) -> Any:
"""Exit."""
request = AppUtilitiesProtoModule.ExitRequest()
response = self.service.exit(request)
return response
hpohekar marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 3 additions & 3 deletions src/ansys/fluent/core/services/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,10 @@ def _get_request_instance_for_path(request_class, path: str) -> Any:
class SettingsService:
"""Service for accessing and modifying Fluent settings."""

def __init__(self, channel, metadata, scheme_eval, fluent_error_state) -> None:
def __init__(self, channel, metadata, app_utilities, fluent_error_state) -> None:
"""__init__ method of SettingsService class."""
self._service_impl = _SettingsServiceImpl(channel, metadata, fluent_error_state)
self._scheme_eval = scheme_eval
self._app_utilities = app_utilities

@_trace
def _set_state_from_value(self, state: SettingsModule.Value, value: Any):
Expand Down Expand Up @@ -369,7 +369,7 @@ def has_wildcard(self, name: str) -> bool:
"""Checks whether a name has a wildcard pattern."""
return self._scheme_eval.is_defined(
"has-fnmatch-wild-card?"
) and self._scheme_eval.scheme_eval(f'(has-fnmatch-wild-card? "{name}")')
) and self._app_utilities.is_wildcard(name)

@_trace
def is_interactive_mode(self) -> bool:
Expand Down
Loading
Loading