Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
85 changes: 78 additions & 7 deletions src/ansys/dpf/core/result_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import traceback
import warnings

from typing import List, Union
from enum import Enum, unique
from types import SimpleNamespace
from ansys.dpf.gate import (
Expand All @@ -24,6 +25,9 @@
from ansys.dpf.core.cyclic_support import CyclicSupport
from ansys.dpf.core.label_space import LabelSpace
from ansys.dpf.core.check_version import version_requires
from ansys.dpf.core.dimensionality import natures
from ansys.dpf.core.common import locations
from ansys.dpf.core.available_result import Homogeneity


@unique
Expand Down Expand Up @@ -61,14 +65,25 @@ class ResultInfo:

This class describes the metadata of the analysis and the available results.

.. note::
Creating a new ResultInfo from an analysis type and physics type is currently only available
Copy link
Contributor

Choose a reason for hiding this comment

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

I see that you add more more capabilities available witha single server type, I'm afraid that it's going to make the library hard to use :/ (I found the issue with the streams class 2 days ago)

Copy link
Contributor

Choose a reason for hiding this comment

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

Are you following up to expand to other server types after?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cbellot000 definitely, yes. But this can be merged first to allow for a custom operator to create a ResultInfo.

InProcess.

Parameters
----------
result_info : ctypes.c_void_p, ansys.grpc.dpf.result_info_pb2.ResultInfo message
result_info: ctypes.c_void_p, ansys.grpc.dpf.result_info_pb2.ResultInfo
Existing ResultInfo internal object

server: ansys.dpf.core.server, optional
Server with the channel connected to the remote or local instance.
The default is ``None``, in which case an attempt is made to use the
global server.

analysis_type: analysis_types
Type of the analysis for a new ResultInfo.

server : ansys.dpf.core.server, optional
Server with the channel connected to the remote or local instance.
The default is ``None``, in which case an attempt is made to use the
global server.
physics_type: physics_types
Type of physics for the new ResultInfo.

Examples
--------
Expand All @@ -87,7 +102,7 @@ class ResultInfo:

"""

def __init__(self, result_info, server=None):
def __init__(self, result_info=None, server=None, analysis_type: analysis_types = None, physics_type: physics_types = None):
"""Initialize with a ResultInfo message"""
# ############################
# step 1: get server
Expand All @@ -109,7 +124,13 @@ def __init__(self, result_info, server=None):
else:
self._internal_obj = result_info
elif result_info is None:
raise Exception("Result_info given is None")
if not self._server.has_client():
if not (analysis_type or physics_type):
self._internal_obj = None
raise ValueError("Creating a new ResultInfo requires an analysis_type and a physics_type.")
self._internal_obj = self._api.result_info_new(analysis_type=analysis_type.value, physics_type=physics_type.value)
else:
raise NotImplementedError("Cannot create a new ResultInfo via gRPC.")

def __str__(self):
try:
Expand Down Expand Up @@ -158,6 +179,56 @@ def _names(self):
def __contains__(self, value):
return value in self._names

def add_result(
self,
operator_name: str,
scripting_name: str,
homogeneity: Homogeneity,
location: locations,
nature: natures,
dimensions: Union[List[int], None] = None,
description: str = "",
):
"""Add an available result to the ResultInfo.

.. note::
Adding a new result to a ResultInfo is currently only available InProcess.

Parameters
----------
operator_name:
Name of the DPF operator to use for result extraction.
scripting_name:
Name to use when requesting the result.
homogeneity:
Homogeneity of the result.
location:
Location of the result.
nature:
Mathematical nature of the result (scalar, vector...).
dimensions:
List of dimensions of the result when vector or matrix.
Enter ``[N]`` for an N-size vector result.
Enter ``[N, M]`` for a rank-2, NxM matrix result.
For example:
* ``[3]``: 3d vector
* ``[3, 3]``: ``3 x 3`` matrix
description:
Description of the result.
"""
if self._server.has_client():
raise NotImplementedError("Cannot add a result to a ResultInfo via gRPC.")
if nature == natures.scalar:
dimensions = [1]
else:
if not dimensions:
raise ValueError(f"Argument 'dimensions' is required for a {nature.name} result.")
size_dim = len(dimensions)
self._api.result_info_add_result(
self, operator_name, scripting_name, dimensions,
size_dim, nature.value, location, homogeneity.name, description
)

@property
def analysis_type(self):
"""Retrieves the analysis type.
Expand Down
79 changes: 79 additions & 0 deletions tests/test_resultinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from ansys.dpf.core import Model
from conftest import (
SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_5_0,
SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_6_0,
SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_0,
SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_7_1,
SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_8_0,
Expand Down Expand Up @@ -165,3 +166,81 @@ def test_result_info_memory_leaks(model):
# j = res.job_name
# n = res.product_name
# t = res.main_title


def test_create_result_info(server_type):
from ansys.dpf.core.available_result import Homogeneity
if not server_type.has_client():
result_info = dpf.core.ResultInfo(
analysis_type=dpf.core.result_info.analysis_types.static,
physics_type=dpf.core.result_info.physics_types.mechanical,
server=server_type
)
result_info.add_result(
operator_name="operator_name",
scripting_name="scripting_name",
homogeneity=Homogeneity.temperature,
location=dpf.core.locations.nodal,
nature=dpf.core.natures.scalar,
dimensions=None,
description="description",
)
if SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_6_0:
ref = """Static analysis
Unit system: Undefined
Physics Type: Mechanical
Available results:
- scripting_name: Nodal Scripting Name
"""
elif SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_5_0:
ref = """Static analysis
Unit system: Undefined
Physics Type: Mecanic
Available results:
- scripting_name: Nodal Scripting Name"""
else:
ref = """Static analysis
Unit system:
Physics Type: Mecanic
Available results:
- scripting_name: Nodal Scripting Name"""
assert str(result_info) == ref
with pytest.raises(ValueError, match="requires"):
_ = dpf.core.ResultInfo()
else:
with pytest.raises(NotImplementedError, match="Cannot create a new ResultInfo via gRPC."):
_ = dpf.core.ResultInfo(
analysis_type=dpf.core.result_info.analysis_types.static,
physics_type=dpf.core.result_info.physics_types.mechanical,
server=server_type
)


def test_result_info_add_result(model):
from ansys.dpf.core.available_result import Homogeneity
res = model.metadata.result_info
if not model._server.has_client():
res.add_result(
operator_name="operator_name",
scripting_name="scripting_name",
homogeneity=Homogeneity.temperature,
location=dpf.core.locations.nodal,
nature=dpf.core.natures.scalar,
dimensions=None,
description="description",
)
else:
with pytest.raises(
NotImplementedError,
match="Cannot add a result to a ResultInfo via gRPC."
):
res.add_result(
operator_name="operator_name",
scripting_name="scripting_name",
homogeneity=Homogeneity.temperature,
location=dpf.core.locations.nodal,
nature=dpf.core.natures.scalar,
dimensions=None,
description="description",
)