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
66 changes: 66 additions & 0 deletions ansys/modelcenter/workflow/api/itradestudy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""Defines interfaces and types for working with trade studies."""

from abc import ABC, abstractmethod
from typing import Mapping, Sequence

import ansys.engineeringworkflow.api as aew_api
import ansys.tools.variableinterop as atvi


class TradeStudyRun:
"""A structure that represents a snapshot of the state of a trade study run."""

def __init__(
self,
input_values: Mapping[str, atvi.VariableState],
output_values: Mapping[str, atvi.VariableState],
run_state: aew_api.WorkflowInstanceState,
):
"""Initialize a new instance."""
self._input_values: Mapping[str, atvi.VariableState] = input_values
self._output_values: Mapping[str, atvi.VariableState] = output_values
self._run_state: aew_api.WorkflowInstanceState = run_state

@property
def input_values(self) -> Mapping[str, atvi.VariableState]:
"""Get the input values for this run."""
return self._input_values

@property
def output_values(self) -> Mapping[str, atvi.VariableState]:
"""Get the output values for this run."""
return self._output_values

@property
def run_state(self) -> aew_api.WorkflowInstanceState:
"""Get the state of this run."""
return self._run_state

# TODO: something to get error messages?


class ITradeStudy(ABC):
"""Represents a trade study."""

@abstractmethod
def study_state(self) -> aew_api.WorkflowInstanceState:
"""The state of the trade study overall."""
# TODO: Define rules for the state.
# For example, if any run is errored, does that mean the whole thing?
# Even if there are still other runs in progress?
# Is this enum appropriate for this or do we need another one?

# TODO: is this even what we want? Or something more involved?
# A stream of completed runs as they come in, for example.
# We could do both, or implement a simpler version first and add
# something more complex later if we see customer / ACE demand.
@abstractmethod
def get_current_run_state(self) -> Sequence[TradeStudyRun]:
"""Get the current run table."""

def add_runs(self, additional_runs: Sequence[TradeStudyRun]) -> None:
"""
Append additional runs to the trade study.

The engine will immediately attempt to schedule these runs.
"""
25 changes: 24 additions & 1 deletion ansys/modelcenter/workflow/api/iworkflow.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Definition of workflow."""
from abc import ABC, abstractmethod
from typing import Collection, Optional, Tuple, Union
from typing import Collection, Mapping, Optional, Sequence, Tuple, Union

import ansys.engineeringworkflow.api as aew_api
import ansys.tools.variableinterop as atvi
Expand All @@ -9,6 +9,7 @@
from ansys.modelcenter.workflow.api.icomponent import IComponent
from ansys.modelcenter.workflow.api.idatapin import IDatapin
from ansys.modelcenter.workflow.api.idatapin_link import IDatapinLink
from ansys.modelcenter.workflow.api.itradestudy import ITradeStudy, TradeStudyRun


class IWorkflow(aew_api.IWorkflowInstance, ABC):
Expand Down Expand Up @@ -271,3 +272,25 @@ def create_component(
IComponent
The created component.
"""

@abstractmethod
def create_trade_study(
self,
inputs: Mapping[str, atvi.CommonVariableMetadata],
outputs: Mapping[str, atvi.CommonVariableMetadata],
runs: Optional[Sequence[TradeStudyRun]] = None,
) -> ITradeStudy:
"""
Create a trade study.

The engine will immediately attempt to schedule these runs.

Parameters
----------
inputs: The inputs in the trade study.
Each run must supply values for each of these inputs.
outputs: The outputs in the trade study.
The values for each of these outputs will be captured when the run completes.
runs: The runs to include in the study.
If any runs are supplied, the runs are scheduled immediately.
"""