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

Add fluid result averaging, FluidMeshInfo, and Faces #435

Merged
merged 43 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
15fa5da
Raise for plot on empty Dataframe
PProfizi Jul 21, 2023
25ac22b
Add location argument to generic result requests
PProfizi Jul 21, 2023
c4a3a3a
Integrated results mass_flow_rate and surface_heat_rate are only avai…
PProfizi Jul 21, 2023
4864351
Mark integrated results
PProfizi Jul 21, 2023
db5e6ec
Fix and mark requests on cells as filtering-out face zone IDs
PProfizi Jul 21, 2023
f8584c8
Introduce the native_location dynamic argument
PProfizi Jul 21, 2023
47ce406
Add first averaging tests for fluid
PProfizi Jul 21, 2023
d3eb81f
Fix surface_heat_rate and surface_heat_rate_on_faces
PProfizi Jul 24, 2023
4eb1146
Add back enthalpy_on_faces
PProfizi Jul 24, 2023
2a972ec
Allow query of surface_heat_rate (on faces) using a list of cell IDs
PProfizi Jul 24, 2023
a222f4a
Add face methods in selection.py: select_faces, select_nodes_of_faces…
PProfizi Jul 24, 2023
d99e7fd
Update FluidSimulation._build_selection to correctly handle requests …
PProfizi Jul 24, 2023
a7c6035
Add Mesh.num_faces, Mesh.faces, Mesh.face_to_node_ids_connectivity, M…
PProfizi Jul 24, 2023
c262013
Add faces.py
PProfizi Jul 24, 2023
55b9bdc
Add Mesh.face_ids
PProfizi Jul 24, 2023
1926b86
Raise on dataframe.plot when empty mesh index
PProfizi Jul 24, 2023
7480605
Fix Selection.select_nodes_of_faces
PProfizi Jul 24, 2023
89bf70a
Only ask to filter cell zones on request with zones or qualifiers for…
PProfizi Jul 24, 2023
47f6774
Add test_mesh_faces
PProfizi Jul 24, 2023
e729957
Raise in FluidSimulation result APIs when result is not available (sh…
PProfizi Jul 24, 2023
8402461
Move mesh_info pproperty from Simulation to FluidSimulation
PProfizi Jul 25, 2023
2877d39
Commit new fluid tests for averaging and cross location requests
PProfizi Jul 25, 2023
ef1b6fe
Add MeshInfo, simplify 'zones' to cell_zones and face_zones dictionaries
PProfizi Jul 25, 2023
6b62ee9
Add MeshInfo.cell_zones_to_face_zones
PProfizi Jul 25, 2023
15d3b9d
Fix FluidSimulation._try_get_result_info
PProfizi Jul 25, 2023
1158676
Add filtering of zones for ElementalAndFaces and raise due to current…
PProfizi Jul 25, 2023
1db1a9c
Fix test_fluid_simulation_result_unavailable
PProfizi Jul 25, 2023
e7c5eff
Fix raise error when querying ElementalAndFaces results with a face_s…
PProfizi Jul 25, 2023
27f2d9d
Remove capability to ask for results on faces using cell_ids -> trans…
PProfizi Jul 25, 2023
adf6287
Update test_fluid_simulation.py with raise error on ElementalAndFaces…
PProfizi Jul 25, 2023
a356bce
Fix test since cell_ids not available for query on face results
PProfizi Jul 25, 2023
4fe9478
Fix Mesh docstrings
PProfizi Jul 25, 2023
76a63b2
Fix retro
PProfizi Jul 25, 2023
1dc7a69
Add coverage to faces.py
PProfizi Jul 26, 2023
46e6658
Improve coverage of mesh.py
PProfizi Jul 26, 2023
785d1d2
Improve coverage of mesh_info.py
PProfizi Jul 26, 2023
3e889f4
Improve coverage of selection.py
PProfizi Jul 26, 2023
2943594
Fix MeshInfo docstring
PProfizi Jul 26, 2023
ea7b6da
Update FluidMeshInfo docstring
PProfizi Jul 26, 2023
77c29c2
Update faces.py
PProfizi Jul 26, 2023
0dbf302
Fix MeshInfo docstring
PProfizi Jul 26, 2023
f76a819
Fix test_spatial_selection_select_named_selection
PProfizi Jul 26, 2023
4204663
Update test_fluid_simulation.py per comments
PProfizi Jul 26, 2023
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
1 change: 0 additions & 1 deletion src/ansys/dpf/post/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
from ansys.dpf.post.transient_mechanical_simulation import ( # noqa: F401
TransientMechanicalSimulation,
)
from ansys.dpf.post.zone import Zone, Zones # noqa: F401

# this must be after some ansys.dpf.post import
__version__ = importlib_metadata.version("ansys-dpf-post")
Expand Down
4 changes: 4 additions & 0 deletions src/ansys/dpf/post/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,8 @@
The interactive plotter object used for plotting.

"""
if len(self.index.mesh_index) == 0:
raise ValueError("Cannot plot a Dataframe with an empty mesh index.")
label_space = {}
if kwargs != {}:
axis_kwargs, kwargs = self._filter_arguments(arguments=kwargs)
Expand Down Expand Up @@ -772,6 +774,8 @@
fc = self._fc
label_space = fc.get_label_space(0)

if len(fc) == 0:
raise ValueError("No data to plot.")

Check warning on line 778 in src/ansys/dpf/post/dataframe.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/dataframe.py#L778

Added line #L778 was not covered by tests
for field in fc:
# Treat multi-layer field
shell_layer_check = field.shell_layers
Expand Down
158 changes: 158 additions & 0 deletions src/ansys/dpf/post/faces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
"""This module contains Face and Faces classes."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import List

from ansys.dpf.core import errors
from ansys.dpf.core import faces as core_faces
from ansys.dpf.core.nodes import Node

from ansys.dpf.post.elements import ElementType


class Face:
"""Proxy class wrapping dpf.core.faces.Face."""

def __init__(self, face: core_faces.Face):
"""Constructs a Proxy Face object."""
self._face = face

@property
def node_ids(self) -> List[int]:
"""See :py:meth:`ansys.dpf.core.faces.Face.node_ids`."""
return self._face.node_ids

Check warning on line 25 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L25

Added line #L25 was not covered by tests

@property
def id(self) -> int:
"""See :py:meth:`ansys.dpf.core.faces.Face.id`."""
return self._face.id

@property
def index(self) -> int:
"""See :py:meth:`ansys.dpf.core.faces.Face.index`."""
return self._face.index

@property
def nodes(self) -> List[Node]:
"""See :py:meth:`ansys.dpf.core.faces.Face.nodes`."""
return self._face.nodes

Check warning on line 40 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L40

Added line #L40 was not covered by tests

@property
def num_nodes(self) -> int:
"""See :py:meth:`ansys.dpf.core.faces.Face.n_nodes`."""
return self._face.n_nodes

Check warning on line 45 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L45

Added line #L45 was not covered by tests

@property
def type_info(self) -> ElementType:
"""Gets an element descriptor, See :py:meth:`ansys.dpf.core.faces.Face.id`."""
return ElementType(self._face.type.value)

Check warning on line 50 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L50

Added line #L50 was not covered by tests

@property
def type(self) -> core_elements.element_types:
"""Returns the Element Type."""
return self._face.type

Check warning on line 55 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L55

Added line #L55 was not covered by tests

@property
def to_node_connectivity(self) -> List[int]:
"""See :py:meth:`ansys.dpf.core.faces.Face.connectivity`."""
return self._face.connectivity

Check warning on line 60 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L60

Added line #L60 was not covered by tests

def __repr__(self) -> str:
"""Returns string representation of a Face."""
return f"Face(type={self.type},index={self.index},id={self.id})"

Check warning on line 64 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L64

Added line #L64 was not covered by tests

def __str__(self) -> str:
"""Returns string representation of a Face."""
return str(self._face)

Check warning on line 68 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L68

Added line #L68 was not covered by tests


class _FaceList(ABC):
"""Iterator class for the FaceList."""

def __init__(self, face_list: core_faces.Faces):
"""Constructs an Iterator from a face list."""
self._face_list = face_list
self._idx = 0

def __next__(self) -> Face:
"""Returns the next Face in the list."""
if self._idx >= len(self._face_list):
raise StopIteration
ret = self[self._idx]
self._idx += 1
return ret

Check warning on line 85 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L81-L85

Added lines #L81 - L85 were not covered by tests

def __getitem__(self, index: int) -> Face:
"""Returns a post.Face based on an index in the current list."""
return Face(self._face_list[index])

def __len__(self) -> int:
"""Returns the number of faces in the list."""
return self._face_list.n_faces

def __repr__(self) -> str:
"""Returns a string representation of _FaceList object."""
return f"{self.__class__.__name__}({self}, __len__={len(self)})"

Check warning on line 97 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L97

Added line #L97 was not covered by tests

def _short_list(self) -> str:
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure that name is appropriate regarding what the function does...

_str = "["
if self.__len__() > 3:
_fst = Face(self._face_list[0]).type_info.name
_lst = Face(self._face_list[len(self) - 1]).type_info.name
_str += f"{_fst}, ..., {_lst}"

Check warning on line 104 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L100-L104

Added lines #L100 - L104 were not covered by tests
else:
face_list = [Face(self._face_list[idx]) for idx in range(len(self))]
_str += ", ".join(map(lambda el: el.type_info.name, face_list))
_str += "]"
return _str

Check warning on line 109 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L106-L109

Added lines #L106 - L109 were not covered by tests

def __str__(self) -> str:
"""Returns a string representation of a _FaceList object."""
return self._short_list()

Check warning on line 113 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L113

Added line #L113 was not covered by tests

@abstractmethod
def __iter__(self): # pragma: no cover
"""Returns the object to iterate on."""
PProfizi marked this conversation as resolved.
Show resolved Hide resolved


class FaceListByIndex(_FaceList):
"""Face list object using indexes as input."""

@property
def by_id(self) -> FaceListById:
"""Returns an equivalent list which accepts IDs as input."""
return FaceListById(self._face_list)

def __iter__(self) -> FaceListByIndex:
"""Returns the object to iterate over."""
self._idx = 0
return self

Check warning on line 131 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L130-L131

Added lines #L130 - L131 were not covered by tests

def __contains__(self, face: Face) -> bool:
"""Checks if the given element in the list."""
return len(self) > face.index >= 0

Check warning on line 135 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L135

Added line #L135 was not covered by tests


class FaceListById(_FaceList):
"""Face list object using IDs as input."""

def __getitem__(self, id: int) -> Face: # pylint: disable=redefined-builtin
"""Access a Face with an ID."""
idx = self._face_list.scoping.index(id)
try:
return super().__getitem__(idx)
except errors.DPFServerException as e:
if "face not found" in str(e):
raise ValueError(f"Face with ID={id} not found in the list.")

Check warning on line 148 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L146-L148

Added lines #L146 - L148 were not covered by tests
else:
raise e # pragma: no cover

def __contains__(self, face: Face) -> bool:
"""Checks if the given face is in the list."""
return face.id in self._face_list.scoping.ids

Check warning on line 154 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L154

Added line #L154 was not covered by tests

def __iter__(self) -> FaceListByIndex:
"""Returns the object to iterate over."""
return FaceListByIndex(self._face_list)

Check warning on line 158 in src/ansys/dpf/post/faces.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/dpf/post/faces.py#L158

Added line #L158 was not covered by tests
Loading