Skip to content

Commit

Permalink
feat: reintroduce surface evolution pp (#118)
Browse files Browse the repository at this point in the history
  • Loading branch information
msd-11 authored Jan 14, 2025
1 parent f250b0a commit e5bace4
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 91 deletions.
2 changes: 1 addition & 1 deletion doc/source/api_reference/post_processings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Available postprocessings
:inherited-members: PostProcessing


.. autoclass:: SurfaceEvol()
.. autoclass:: SurfaceEvolution()
:members:
:inherited-members: PostProcessing

Expand Down
4 changes: 2 additions & 2 deletions doc/source/api_reference/selections.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ class.
You can use the :meth:`~ansys.simai.core.data.lists.ExportablePPList.export()`
method to export results in batch for exportable postprocessings
(:py:class:`~ansys.simai.core.data.post_processings.GlobalCoefficients`
and :py:class:`~ansys.simai.core.data.post_processings.SurfaceEvol` instances):
and :py:class:`~ansys.simai.core.data.post_processings.SurfaceEvolution` instances):

.. code-block:: python
selection.post.surface_evol(axis="x", delta=13.5).export("xlsx").download(
selection.post.surface_evolution(axis="x", delta=13.5).export("xlsx").download(
"/path/to/file.xlsx"
)
Expand Down
2 changes: 1 addition & 1 deletion src/ansys/simai/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
CustomVolumePointCloud,
GlobalCoefficients,
Slice,
SurfaceEvol,
SurfaceEvolution,
SurfaceVTP,
VolumeVTU,
)
33 changes: 20 additions & 13 deletions src/ansys/simai/core/data/post_processings.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,16 +193,16 @@ def data(self) -> Dict[str, List]:
}


class SurfaceEvol(ExportablePostProcessing):
"""Provides the representation of the ``SurfaceEvol`` object.
class SurfaceEvolution(ExportablePostProcessing):
"""Provides the representation of the ``SurfaceEvolution`` object.
This class is generated through :meth:`PredictionPostProcessings.surface_evol()`
This class is generated through :meth:`PredictionPostProcessings.surface_evolution()`
"""

@property
def data(self) -> DownloadableResult:
""":class:`DownloadableResult` object that allows access to the
``SurfaceEvol`` JSON data, both directly in memory any by downloading it
``SurfaceEvolution`` JSON data, both directly in memory any by downloading it
into a file.
Accessing this property blocks until the data is ready.
Expand All @@ -212,12 +212,17 @@ def data(self) -> DownloadableResult:
return DownloadableResult(results["data"]["resources"]["json"], self._client)

def as_dict(self) -> Dict[str, Any]:
"""Download the SurfaceEvol JSON data and load it as a Python dictionary.
"""Download the SurfaceEvolution JSON data and load it as a Python dictionary.
Accessing this help method blocks until the data is ready.
"""
return json.load(self.data.in_memory())

@classmethod
def _api_name(cls) -> str:
# Name of the postprocessing in API calls. Overriding because the endpoint is SurfaceEvol not SurfaceEvolution
return "SurfaceEvol"


class Slice(PostProcessing):
"""Provides a representation of a slice from the prediction in PNG or VTP format.
Expand Down Expand Up @@ -340,10 +345,12 @@ def global_coefficients(self, run: bool = True) -> Optional[GlobalCoefficients]:
"""
return self._get_or_run(GlobalCoefficients, {}, run)

def surface_evol(self, axis: str, delta: float, run: bool = True) -> Optional[SurfaceEvol]:
"""Compute or get the SurfaceEvol for specific parameters.
def surface_evolution(
self, axis: str, delta: float, run: bool = True
) -> Optional[SurfaceEvolution]:
"""Compute or get the SurfaceEvolution for specific parameters.
This is a non-blocking method. It returns the ``SurfaceEvol``
This is a non-blocking method. It returns the ``SurfaceEvolution``
object without waiting. This object may not have data right away
if computation is still in progress. Data is filled
asynchronously once the computation is finished.
Expand All @@ -355,21 +362,21 @@ def surface_evol(self, axis: str, delta: float, run: bool = True) -> Optional[Su
same parameters do not relaunch it.
Args:
axis: Axis to compute the surface evol for.
axis: Axis to compute the surface evolution for.
delta: Increment of the abscissa in meters.
run: Boolean indicating whether to compute or get the postprocessing.
The default is ``True``. If ``False``, the postprocessing is not
computed, and ``None`` is returned if it does not exist yet.
Returns:
``SurfaceEvol`` that allows access to the values.
``SurfaceEvolution`` that allows access to the values.
Returns ``None`` if ``run=False`` and the postprocessing does not exist.
"""
if axis not in ["x", "y", "z"]:
raise TypeError("Axis must be x, y, or z.")
if not isinstance(delta, numbers.Number) or not (delta > 0):
raise TypeError(f"Delta must be a positive number (got: {delta}).")
return self._get_or_run(SurfaceEvol, {"axis": axis, "delta": delta}, run)
return self._get_or_run(SurfaceEvolution, {"axis": axis, "delta": delta}, run)

def slice(
self, axis: str, coordinate: float, format: str = "png", run: bool = True
Expand Down Expand Up @@ -603,7 +610,7 @@ def _get_or_run(
exits, it gets it.
"""
# FIXME frozenset(params.items()) works as long as there are no
# collision between params (axis and delta for surface evol, param for slice)
# collision between params (axis and delta for surface evolution, param for slice)
# but will be broken if a new type of postprocessings can have
# two params with the same value.
params_frozen = frozenset(params.items())
Expand Down Expand Up @@ -746,7 +753,7 @@ def list(
simai = ansys.simai.core.from_config()
prediction = simai.predictions.list()[0]
post_processings = simai.post_processings.list(
ansys.simai.core.SurfaceEvol, prediction.id
ansys.simai.core.SurfaceEvolution, prediction.id
)
"""
pp_type_str = post_processing_type._api_name() if post_processing_type else None
Expand Down
14 changes: 7 additions & 7 deletions src/ansys/simai/core/data/selection_post_processings.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from ansys.simai.core.data.post_processings import (
GlobalCoefficients,
Slice,
SurfaceEvol,
SurfaceEvolution,
SurfaceVTP,
VolumeVTU,
)
Expand Down Expand Up @@ -66,12 +66,12 @@ def global_coefficients(self) -> ExportablePPList[GlobalCoefficients]:
selection=self._selection, post=lambda pred: pred.post.global_coefficients()
)

def surface_evol(self, axis: str, delta: float) -> ExportablePPList[SurfaceEvol]:
"""Compute or get the SurfaceEvol of the predictions for specific parameters.
def surface_evolution(self, axis: str, delta: float) -> ExportablePPList[SurfaceEvolution]:
"""Compute or get the SurfaceEvolution of the predictions for specific parameters.
This is a non-blocking method. It returns an
:py:class:`~ansys.simai.core.data.lists.ExportablePPList` instance
of :py:class:`~ansys.simai.core.data.post_processings.SurfaceEvol`
of :py:class:`~ansys.simai.core.data.post_processings.SurfaceEvolution`
objects without waiting. Those ``PostProcessing`` objects may not have
data right away if the computation is still in progress. Data is filled
asynchronously once the computation is finished.
Expand All @@ -82,16 +82,16 @@ def surface_evol(self, axis: str, delta: float) -> ExportablePPList[SurfaceEvol]
Subsequent calls with the same parameters do not relaunch it.
Args:
axis: Axis to compute the the SurfaceEvol on.
axis: Axis to compute the the SurfaceEvolution on.
delta: Increment of the abscissa in meters.
Returns:
:py:class:`~ansys.simai.core.data.lists.ExportablePPList` instance of
:py:class:`~ansys.simai.core.data.post_processings.SurfaceEvol` objects.
:py:class:`~ansys.simai.core.data.post_processings.SurfaceEvolution` objects.
"""
return ExportablePPList(
selection=self._selection,
post=lambda pred: pred.post.surface_evol(axis, delta),
post=lambda pred: pred.post.surface_evolution(axis, delta),
)

def slice(self, axis: str, coordinate: float) -> PPList[Slice]:
Expand Down
16 changes: 8 additions & 8 deletions tests/test_post_processing_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ def test_post_processing_global_coefficients_delete(prediction_factory):


@responses.activate
def test_post_processing_surface_evol_delete(prediction_factory):
"""WHEN deleting a SurfaceEvol post-processing from a prediction
def test_post_processing_surface_evolution_delete(prediction_factory):
"""WHEN deleting a SurfaceEvolution post-processing from a prediction
THEN there is a call to the DELETE endpoint
ALSO a new call to pred.post.surface_evol() re-runs the post-processing
ALSO a new call to pred.post.surface_evolution() re-runs the post-processing
"""
pred = prediction_factory()
responses.add(
Expand Down Expand Up @@ -119,10 +119,10 @@ def test_post_processing_surface_evol_delete(prediction_factory):
status=204,
)

surface_evol = pred.post.surface_evol(axis="y", delta=9.5)
assert surface_evol.id == "im-the-first-one"
surface_evolution = pred.post.surface_evolution(axis="y", delta=9.5)
assert surface_evolution.id == "im-the-first-one"

surface_evol.delete()
surface_evolution.delete()

surface_evol = pred.post.surface_evol(axis="y", delta=9.5)
assert surface_evol.id == "im-the-second-one"
surface_evolution = pred.post.surface_evolution(axis="y", delta=9.5)
assert surface_evolution.id == "im-the-second-one"
6 changes: 3 additions & 3 deletions tests/test_post_processing_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ def request_callback(request):


@responses.activate
def test_post_processing_export_surface_evol_excel(simai_client):
"""WHEN I call export() on a SurfaceEvol post-processing
def test_post_processing_export_surface_evolution_excel(simai_client):
"""WHEN I call export() on a SurfaceEvolution post-processing
THEN I get a DownloadableResult object allowing me to download the content.
"""

pp = simai_client._post_processing_directory._model_from(
{"id": "mozeu", "type": "SurfaceEvol", "state": "successful"}
{"id": "mozeu", "type": "SurfaceEvolution", "state": "successful"}
)

def request_callback(request):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_post_processings.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def test_post_processing_dont_run_does_not_exist_locally_with_params(
status=200,
)

pp = pred.post.surface_evol(axis="x", delta=0.5, run=False)
pp = pred.post.surface_evolution(axis="x", delta=0.5, run=False)
assert pp.id == "0002"


Expand Down
20 changes: 10 additions & 10 deletions tests/test_post_processings_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
DownloadableResult,
GlobalCoefficients,
Slice,
SurfaceEvol,
SurfaceEvolution,
SurfaceVTP,
VolumeVTU,
)
Expand Down Expand Up @@ -99,8 +99,8 @@ def test_post_processing_result_global_coefficients(simai_client):


@responses.activate
def test_post_processing_result_surface_evol(simai_client):
"""WHEN Running a SurfaceEvol post-processing on a prediction and calling its .data field,
def test_post_processing_result_surface_evolution(simai_client):
"""WHEN Running a SurfaceEvolution post-processing on a prediction and calling its .data field,
THEN a GET request is made on the post-processings/<id> endpoint
ALSO the .data attribute is a dictionary containing the expected data
ALSO multiple accesses to .data don't call the endpoint multiple times
Expand Down Expand Up @@ -179,15 +179,15 @@ def test_post_processing_result_surface_evol(simai_client):
)

pred = simai_client._prediction_directory._model_from({"id": "r26g04j8", "state": "successful"})
surface_evol = pred.post.surface_evol(axis="x", delta=5)
surface_evolution = pred.post.surface_evolution(axis="x", delta=5)

assert isinstance(surface_evol, SurfaceEvol)
assert isinstance(surface_evol.data, DownloadableResult)
surface_evol_dict = surface_evol.as_dict()
assert len(surface_evol_dict) == 3
assert surface_evol_dict["WallShearStress"]["data"]["X"][0] == 107167.4091582841
assert isinstance(surface_evolution, SurfaceEvolution)
assert isinstance(surface_evolution.data, DownloadableResult)
surface_evolution_dict = surface_evolution.as_dict()
assert len(surface_evolution_dict) == 3
assert surface_evolution_dict["WallShearStress"]["data"]["X"][0] == 107167.4091582841

# we have used surface_evol.data twice, generating 2 hits to the endpoint
# we have used surface_evolution.data twice, generating 2 hits to the endpoint
assert responses.assert_call_count("https://test.test/post-processings/4c7r4c", 2)


Expand Down
Loading

0 comments on commit e5bace4

Please sign in to comment.