Skip to content
Merged
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
283 changes: 166 additions & 117 deletions ansys/api/fluent/v0/field_data_pb2.py

Large diffs are not rendered by default.

137 changes: 58 additions & 79 deletions ansys/fluent/core/services/field_data.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Wrappers over FieldData grpc service of Fluent."""

from functools import reduce
from typing import Dict, List, Optional

import grpc
Expand Down Expand Up @@ -121,33 +122,35 @@ class FieldData:

Methods
-------
def get_surfaces(
add_get_surfaces_request(
surface_ids: List[int],
overset_mesh: bool = False,
provide_vertices=True,
provide_faces=True,
provide_faces_centroid=False,
provide_faces_normal=False,
) -> Dict[int, Dict]
Get surfaces data i.e. vertices, faces connectivity, centroids and normals.
) -> None
Add request to get surfaces data i.e. vertices, faces connectivity,
centroids and normals.

get_scalar_field(
add_get_scalar_fields_request(
surface_ids: List[int],
scalar_field: str,
node_value: Optional[bool] = True,
boundary_value: Optional[bool] = False,
) -> Dict[int, Dict]:
Get scalar field data i.e. surface data and associated
scalar field values.
) -> None
Add request to get scalar field data on surfaces.

get_vector_field(
add_get_vector_fields_request(
surface_ids: List[int],
vector_field: Optional[str] = "velocity",
scalar_field: Optional[str] = "",
node_value: Optional[bool] = False,
) -> Dict[int, Dict]:
Get vector field data i.e. surface data and associated
scalar and vector field values.
vector_field: Optional[str] = "velocity"
) -> None
Add request to get vector field data on surfaces.

get_fields(self) -> Dict[int, Dict]
Provide data for previously added requests.
Data is returned as dictionary of dictionaries in following structure:
tag_id [int]-> surface_id [int] -> field_name [str] -> field_data
"""

# data mapping
Expand All @@ -159,9 +162,16 @@ def get_surfaces(
}
_chunk_size = 256 * 1024
_bytes_stream = True
_payloadTags = {
FieldDataProtoModule.PayloadTag.OVERSET_MESH: 1,
FieldDataProtoModule.PayloadTag.ELEMENT_LOCATION: 2,
FieldDataProtoModule.PayloadTag.NODE_LOCATION: 4,
FieldDataProtoModule.PayloadTag.BOUNDARY_VALUES: 8,
}

def __init__(self, service: FieldDataService):
self.__service = service
self._fields_request = None

def _extract_fields(self, chunk_iterator):
def _extract_field(field_datatype, field_size, chunk_iterator):
Expand Down Expand Up @@ -199,33 +209,48 @@ def _extract_field(field_datatype, field_size, chunk_iterator):

fields_data = {}
for chunk in chunk_iterator:

payload_info = chunk.payloadInfo
surface_id = payload_info.surfaceId
surface_data = fields_data.get(surface_id)
field = _extract_field(
self._proto_field_type_to_np_data_type[payload_info.fieldType],
payload_info.fieldSize,
chunk_iterator,
)

surface_id = payload_info.surfaceId
payload_tag_id = reduce(
lambda x, y: x | y,
[self._payloadTags[tag] for tag in payload_info.payloadTag]
or [0],
)
payload_data = fields_data.get(payload_tag_id)
if not payload_data:
payload_data = fields_data[payload_tag_id] = {}
surface_data = payload_data.get(surface_id)
if surface_data:
surface_data.update({payload_info.fieldName: field})
else:
fields_data[surface_id] = {payload_info.fieldName: field}
payload_data[surface_id] = {payload_info.fieldName: field}
return fields_data

def get_surfaces(
def _get_fields_request(self):
if not self._fields_request:
self._fields_request = FieldDataProtoModule.GetFieldsRequest(
provideBytesStream=self._bytes_stream,
chunkSize=self._chunk_size,
)
return self._fields_request

def add_get_surfaces_request(
self,
surface_ids: List[int],
overset_mesh: bool = False,
provide_vertices=True,
provide_faces=True,
provide_faces_centroid=False,
provide_faces_normal=False,
) -> Dict[int, Dict]:
request = FieldDataProtoModule.GetFieldsRequest(
provideBytesStream=self._bytes_stream, chunkSize=self._chunk_size
)
request.surfaceRequest.extend(
) -> None:
self._get_fields_request().surfaceRequest.extend(
[
FieldDataProtoModule.SurfaceRequest(
surfaceId=surface_id,
Expand All @@ -238,32 +263,15 @@ def get_surfaces(
for surface_id in surface_ids
]
)
return self._extract_fields(self.__service.get_fields(request))

def get_scalar_field(
def add_get_scalar_fields_request(
self,
surface_ids: List[int],
field_name: str,
node_value: Optional[bool] = True,
boundary_value: Optional[bool] = False,
) -> Dict[int, Dict]:
request = FieldDataProtoModule.GetFieldsRequest(
provideBytesStream=self._bytes_stream, chunkSize=self._chunk_size
)
request.surfaceRequest.extend(
[
FieldDataProtoModule.SurfaceRequest(
surfaceId=surface_id,
oversetMesh=False,
provideFaces=True,
provideVertices=True,
provideFacesCentroid=False,
provideFacesNormal=False,
)
for surface_id in surface_ids
]
)
request.scalarFieldRequest.extend(
) -> None:
self._get_fields_request().scalarFieldRequest.extend(
[
FieldDataProtoModule.ScalarFieldRequest(
surfaceId=surface_id,
Expand All @@ -276,46 +284,13 @@ def get_scalar_field(
for surface_id in surface_ids
]
)
return self._extract_fields(self.__service.get_fields(request))

def get_vector_field(
def add_get_vector_fields_request(
self,
surface_ids: List[int],
vector_field: Optional[str] = "velocity",
field_name: Optional[str] = "",
node_value: Optional[bool] = False,
) -> Dict[int, Dict]:
request = FieldDataProtoModule.GetFieldsRequest(
provideBytesStream=self._bytes_stream, chunkSize=self._chunk_size
)
request.surfaceRequest.extend(
[
FieldDataProtoModule.SurfaceRequest(
surfaceId=surface_id,
oversetMesh=False,
provideFaces=True,
provideVertices=True,
provideFacesCentroid=False,
provideFacesNormal=False,
)
for surface_id in surface_ids
]
)
if field_name:
request.scalarFieldRequest.extend(
[
FieldDataProtoModule.ScalarFieldRequest(
surfaceId=surface_id,
scalarFieldName=field_name,
dataLocation=FieldDataProtoModule.DataLocation.Nodes
if node_value
else FieldDataProtoModule.DataLocation.Elements,
provideBoundaryValues=boundary_value,
)
for surface_id in surface_ids
]
)
request.vectorFieldRequest.extend(
) -> None:
self._get_fields_request().vectorFieldRequest.extend(
[
FieldDataProtoModule.VectorFieldRequest(
surfaceId=surface_id,
Expand All @@ -324,4 +299,8 @@ def get_vector_field(
for surface_id in surface_ids
]
)

def get_fields(self) -> Dict[int, Dict]:
request = self._get_fields_request()
self._fields_request = None
return self._extract_fields(self.__service.get_fields(request))
48 changes: 19 additions & 29 deletions ansys/fluent/core/utils/dump_session_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,34 +52,24 @@ def dump_session_data(
"cell_value"
] = session.field_info.get_range(field, False, [surface])

session_data["scalar-field"] = {}
session.field_data.add_get_surfaces_request(
surfaces_id, provide_faces_centroid=True, provide_faces_normal=True
)
for field in fields:
session_data["scalar-field"][field] = {}
for surface in surfaces_id:
session_data["scalar-field"][field][surface] = {}
session_data["scalar-field"][field][surface][
"node_value"
] = session.field_data.get_scalar_field([surface], field, True)[
surface
]
session_data["scalar-field"][field][surface][
"cell_value"
] = session.field_data.get_scalar_field([surface], field, False)[
surface
]

session_data["surfaces"] = {}
for surface in surfaces_id:
session_data["surfaces"][surface] = session.field_data.get_surfaces(
[surface]
)[surface]

session_data["vector-field"] = {}
for surface in surfaces_id:
session_data["vector-field"][
surface
] = session.field_data.get_vector_field([surface])[surface]
session.field_data.add_get_scalar_fields_request(
surfaces_id, field, True, boundary_value=False
)
session.field_data.add_get_scalar_fields_request(
surfaces_id, field, False, boundary_value=False
)
session.field_data.add_get_scalar_fields_request(
surfaces_id, field, True, boundary_value=True
)
session.field_data.add_get_scalar_fields_request(
surfaces_id, field, False, boundary_value=True
)
session.field_data.add_get_vector_fields_request(surfaces_id)
session_data["fields"] = session.field_data.get_fields()

pickle_obj = open(file_path, "wb")
pickle.dump(session_data, pickle_obj)
pickle_obj.close()
with open(file_path, "wb") as pickle_obj:
pickle.dump(session_data, pickle_obj)
43 changes: 36 additions & 7 deletions ansys/fluent/post/matplotlib/matplot_windows_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import numpy as np

from ansys.api.fluent.v0.field_data_pb2 import PayloadTag
from ansys.fluent.core.session import Session
from ansys.fluent.core.utils.generic import AbstractSingletonMeta, in_notebook
from ansys.fluent.post import get_config
Expand Down Expand Up @@ -135,22 +136,50 @@ def _get_xy_plot_data(self):
)
for id in surfaces_info[surf]["surface_id"]
]

# get scalar field data
data = field_data.get_scalar_field(
field_data.add_get_surfaces_request(
surface_ids,
provide_faces=False,
provide_vertices=True if node_values else False,
provide_faces_centroid=False if node_values else True,
)
field_data.add_get_scalar_fields_request(
surface_ids,
field,
True,
node_values,
boundary_values,
)

location_tag = (
field_data._payloadTags[PayloadTag.NODE_LOCATION]
if node_values
else field_data._payloadTags[PayloadTag.ELEMENT_LOCATION]
)
boundary_value_tag = (
field_data._payloadTags[PayloadTag.BOUNDARY_VALUES]
if boundary_values
else 0
)
surface_tag = 0
xyplot_payload_data = field_data.get_fields()
data_tag = location_tag | boundary_value_tag
xyplot_data = xyplot_payload_data[data_tag]
surface_data = xyplot_payload_data[surface_tag]

# loop over all meshes
xy_plots_data = {}
surfaces_list_iter = iter(surfaces_list)
for surface_id, mesh_data in data.items():
mesh_data["vertices"].shape = mesh_data["vertices"].size // 3, 3
faces = mesh_data["faces"]
y_values = mesh_data[field]
x_values = np.matmul(mesh_data["vertices"], direction_vector)
for surface_id, mesh_data in surface_data.items():
mesh_data["vertices" if node_values else "centroid"].shape = (
mesh_data["vertices" if node_values else "centroid"].size // 3,
3,
)
y_values = xyplot_data[surface_id][field]
x_values = np.matmul(
mesh_data["vertices" if node_values else "centroid"],
direction_vector,
)
structured_data = np.empty(
x_values.size,
dtype={
Expand Down
Loading