Skip to content

Commit 1a10648

Browse files
authored
feat: Add mesh reading capability to case reader. (#3261)
* feat: Add mesh reading capability to case reader. * Remove docstring. * correct a typo. * Implement attribute calls. * Updates.
1 parent 2fcfb38 commit 1a10648

File tree

3 files changed

+94
-11
lines changed

3 files changed

+94
-11
lines changed

src/ansys/fluent/core/filereader/case_file.py

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"""
1717

1818
import codecs
19+
from enum import Enum
1920
import gzip
2021
import os
2122
from os.path import dirname
@@ -215,6 +216,14 @@ def __getattr__(self, name: str):
215216
return CaseVariable(self._variables, name + "/")
216217

217218

219+
class MeshType(Enum):
220+
"""Types of Mesh."""
221+
222+
SURFACE = "surface"
223+
VOLUME = "volume"
224+
UNKNOWN = "unknown"
225+
226+
218227
class Mesh:
219228
"""Class to provide mesh data.
220229
@@ -236,6 +245,16 @@ def __init__(self, file_handle):
236245
"""Initialize the object."""
237246
self._file_handle = file_handle
238247

248+
def get_mesh_type(self) -> MeshType:
249+
"""Returns the type of the mesh."""
250+
try:
251+
if "cells" in self._file_handle["meshes"]["1"].keys():
252+
return MeshType.VOLUME
253+
else:
254+
return MeshType.SURFACE
255+
except Exception:
256+
return MeshType.UNKNOWN
257+
239258
def get_surface_ids(self) -> list:
240259
"""Returns list of ids of all available surfaces."""
241260
id_data = self._file_handle["meshes"]["1"]["faces"]["zoneTopology"]["id"]
@@ -528,6 +547,16 @@ def __init__(self, settings_file_name: Optional[str] = None) -> None:
528547
super().__init__(rp_vars_str)
529548

530549

550+
class EmptyContainer:
551+
"""Empty Container."""
552+
553+
def __getattr__(self, item):
554+
return lambda *args, **kwargs: None
555+
556+
def __call__(self, *args, **kwargs):
557+
return None
558+
559+
531560
class CaseFile(RPVarProcessor):
532561
"""Class to read a Fluent case file.
533562
@@ -552,6 +581,7 @@ def __init__(
552581
project_file_name : Optional[str]
553582
The path of a project file from which the case file is selected.
554583
"""
584+
self._is_case_file = False
555585

556586
if (not case_file_name) == (not project_file_name):
557587
raise RuntimeError(
@@ -572,23 +602,35 @@ def __init__(
572602
)
573603

574604
try:
575-
if Path(case_file_name).match("*.cas.h5"):
605+
if Path(case_file_name).match("*.cas.h5") or Path(case_file_name).match(
606+
"*.msh.h5"
607+
):
576608
_file = h5py.File(case_file_name)
577-
settings = _file["settings"]
578-
rpvars = settings["Rampant Variables"][0]
579-
rp_vars_str = rpvars.decode()
580-
elif Path(case_file_name).match("*.cas"):
609+
if Path(case_file_name).match("*.cas.h5"):
610+
self._is_case_file = True
611+
settings = _file["settings"]
612+
rpvars = settings["Rampant Variables"][0]
613+
rp_vars_str = rpvars.decode()
614+
elif Path(case_file_name).match("*.cas") or Path(case_file_name).match(
615+
"*.msh"
616+
):
581617
with open(case_file_name, "rb") as _file:
582618
rp_vars_str = _file.read()
583-
rp_vars_str = _get_processed_string(rp_vars_str)
584-
elif Path(case_file_name).match("*.cas.gz"):
619+
if Path(case_file_name).match("*.cas"):
620+
self._is_case_file = True
621+
rp_vars_str = _get_processed_string(rp_vars_str)
622+
elif Path(case_file_name).match("*.cas.gz") or Path(case_file_name).match(
623+
"*.msh.gz"
624+
):
585625
with gzip.open(case_file_name, "rb") as _file:
586626
rp_vars_str = _file.read()
587-
rp_vars_str = _get_processed_string(rp_vars_str)
627+
if Path(case_file_name).match("*.cas.gz"):
628+
self._is_case_file = True
629+
rp_vars_str = _get_processed_string(rp_vars_str)
588630
else:
589631
error_message = (
590632
"Could not read case file. "
591-
"Only valid Case files (.h5, .cas, .cas.gz) can be read. "
633+
"Only valid Case files (.h5, .cas, .cas.gz) or Mesh files (.msh.h5, .msh, .msh.gz) can be read. "
592634
)
593635
raise RuntimeError(error_message)
594636

@@ -603,13 +645,24 @@ def __init__(
603645
except Exception as e:
604646
raise RuntimeError(f"Could not read case file {case_file_name}") from e
605647

606-
super().__init__(rp_vars_str=rp_vars_str)
648+
if self._is_case_file:
649+
super().__init__(rp_vars_str=rp_vars_str)
607650
self._mesh = Mesh(_file)
608651

609652
def get_mesh(self):
610653
"""Get the mesh data."""
611654
return self._mesh
612655

656+
def __getattribute__(self, item):
657+
if (
658+
item != "_is_case_file"
659+
and not self._is_case_file
660+
and item
661+
in set(filter(lambda k: not k.startswith("__"), dir(RPVarProcessor)))
662+
):
663+
return EmptyContainer()
664+
return super().__getattribute__(item)
665+
613666

614667
def _get_processed_string(input_string: bytes) -> str:
615668
"""Processes the input string (binary) with help of an identifier to return it in a

src/ansys/fluent/core/launcher/error_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def _raise_non_gui_exception_in_windows(
5050

5151
if (
5252
launcher_utils.is_windows()
53-
and UIMode(ui_mode) not in [UIMode.GUI and UIMode.HIDDEN_GUI]
53+
and UIMode(ui_mode) not in [UIMode.GUI, UIMode.HIDDEN_GUI]
5454
and product_version < FluentVersion.v241
5555
):
5656
raise InvalidArgument(

tests/test_casereader.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from ansys.fluent.core.filereader.case_file import (
1111
InputParameter,
1212
InputParameterOld,
13+
MeshType,
1314
_get_processed_string,
1415
)
1516
from ansys.fluent.core.filereader.case_file import CaseFile as CaseReader
@@ -293,3 +294,32 @@ def test_lispy_for_quotes():
293294
"x",
294295
'"\n(format \\"\n-------------------------\nRunning Original Settings\n------------------------\n\\")"',
295296
]
297+
298+
299+
def test_mesh_reader():
300+
mesh_file_2d = examples.download_file(
301+
"sample_2d_mesh.msh.h5",
302+
"pyfluent/surface_mesh",
303+
return_without_path=False,
304+
)
305+
mesh_file_3d = examples.download_file(
306+
"mixing_elbow.msh.h5",
307+
"pyfluent/mixing_elbow",
308+
return_without_path=False,
309+
)
310+
case_file = examples.download_file(
311+
"mixing_elbow.cas.h5",
312+
"pyfluent/mixing_elbow",
313+
return_without_path=False,
314+
)
315+
mesh_reader_2d = CaseReader(case_file_name=mesh_file_2d)
316+
mesh_reader_3d = CaseReader(case_file_name=mesh_file_3d)
317+
case_reader = CaseReader(case_file_name=case_file)
318+
319+
assert mesh_reader_2d.get_mesh().get_mesh_type() == MeshType.SURFACE
320+
assert mesh_reader_3d.get_mesh().get_mesh_type() == MeshType.VOLUME
321+
assert case_reader.get_mesh().get_mesh_type() == MeshType.VOLUME
322+
323+
assert mesh_reader_2d.precision() is None
324+
assert mesh_reader_3d.precision() is None
325+
assert case_reader.precision() == 2

0 commit comments

Comments
 (0)