Skip to content

Commit

Permalink
Update hmascii example to new workflow.
Browse files Browse the repository at this point in the history
  • Loading branch information
clemens-fricke authored and j042 committed Sep 1, 2023
1 parent 970c632 commit 8a4cefa
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 72 deletions.
2 changes: 1 addition & 1 deletion examples/load_sample_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def load_sample_file(filename: str, force_reload: bool = False) -> bool:
return True
pathlib.Path.mkdir(local_file.parent, parents=True, exist_ok=True)

url = base_url + filename
url = base_url + str(filename)
response = requests.get(url)
if response.status_code == 200:
with open(local_file, "wb") as f:
Expand Down
34 changes: 19 additions & 15 deletions examples/show_hmascii.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
"""Example showing the import of a hmascii file.
"""
import pathlib

import load_sample_file

import gustaf as gus


def main():
try:
hm_tet = gus.io.hmascii.load(
"../../samples/volumes/tet/3DPipeCorner90Tet.hmascii"
)
hm_hex = gus.io.hmascii.load(
"../../samples/volumes/hex/3DPipeCorner90Hex.hmascii"
)

except BaseException:
raise RuntimeError(
'Can`t find mesh in sample files. '
'Make sure that ``gustaf`` and ``samples`` directory are on '
'the same level!'
)
base_samples_path = pathlib.Path("samples")
tet_file_path = pathlib.Path("volumes/tet/3DPipeCorner90Tet.hmascii")
hex_file_path = pathlib.Path("volumes/hex/3DPipeCorner90Hex.hmascii")

# download the files from the samples repo if they are not loaded already
load_sample_file.load_sample_file(tet_file_path)
load_sample_file.load_sample_file(hex_file_path)

# check direct hmascii load works
hm_tet = gus.io.hmascii.load(base_samples_path / tet_file_path)
# check of load via the default load function works
hm_hex = gus.io.load(base_samples_path / hex_file_path)

gus.show.show_vedo(
["3DPipeCorner90Tet", hm_tet], ["3DPipeCorner90Hex", hm_hex]
["3DPipeCorner90Tet", hm_tet], ["3DPipeCorner90Hex", hm_hex]
)


Expand Down
2 changes: 1 addition & 1 deletion gustaf/io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
O - `export`.
"""

from gustaf.io import ioutils, meshio, mfem, mixd, nutils, hmascii
from gustaf.io import hmascii, ioutils, meshio, mfem, mixd, nutils
from gustaf.io.default import load

__all__ = [
Expand Down
3 changes: 2 additions & 1 deletion gustaf/io/default.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pathlib

from gustaf.io import meshio, mfem, mixd
from gustaf.io import hmascii, meshio, mfem, mixd


def load(fname):
Expand All @@ -22,6 +22,7 @@ def load(fname):
".mixd": mixd.load,
".mfem": mfem.load,
".msh": meshio.load,
".hmascii": hmascii.load,
}

fname = pathlib.Path(fname).resolve()
Expand Down
108 changes: 54 additions & 54 deletions gustaf/io/hmascii.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@
tools -> faces
"""

import numpy as np
import pathlib

import numpy as np

from gustaf import utils
from gustaf.edges import Edges
from gustaf.faces import Faces
from gustaf.volumes import Volumes
from gustaf.edges import Edges
from gustaf import utils


class HMLine:
"""Parse a line from an HMASCII file.
"""
"""Parse a line from an HMASCII file."""

__slots__ = ["name", "values"]

Expand All @@ -40,25 +40,24 @@ def __init__(self, line):
--------
None
"""
self.name = ''
self.values = ''
self.name = ""
self.values = ""

if line[0] == '*':
parts = line[1:].split('(')
if line[0] == "*":
parts = line[1:].split("(")
self.name = parts[0]
if len(parts) > 1:
self.values = [
value.strip('"') for value in parts[1][:-2].split(',')
value.strip('"') for value in parts[1][:-2].split(",")
]


class HMElementType:
"""Store HyperMesh element type information.
"""
"""Store HyperMesh element type information."""

__slots__ = ["number_of_nodes", "subelement", "mesh_type"]

def __init__(self, number_of_nodes, mesh_type, subelement=''):
def __init__(self, number_of_nodes, mesh_type, subelement=""):
"""
Parameters
-----------
Expand All @@ -76,18 +75,18 @@ def __init__(self, number_of_nodes, mesh_type, subelement=''):


class HMComponent:
"""Create a component from an HMASCII line.
"""
"""Create a component from an HMASCII line."""

__slots__ = ["name", "elements"]

element_types = {
'tetra4': HMElementType(4, Volumes, 'tria3'),
'hexa8': HMElementType(8, Volumes, 'quad4'),
'tria3': HMElementType(3, Faces, 'plotel'),
'quad4': HMElementType(4, Faces, 'plotel'),
'plotel': HMElementType(2, Edges),
"tetra4": HMElementType(4, Volumes, "tria3"),
"hexa8": HMElementType(8, Volumes, "quad4"),
"tria3": HMElementType(3, Faces, "plotel"),
"quad4": HMElementType(4, Faces, "plotel"),
"plotel": HMElementType(2, Edges),
}
element_type_preference = ('hexa8', 'tetra4', 'quad4', 'tria3')
element_type_preference = ("hexa8", "tetra4", "quad4", "tria3")

def __init__(self, line):
"""
Expand Down Expand Up @@ -117,11 +116,12 @@ def add_element(self, line):
if element_type not in self.elements:
self.elements[element_type] = list()
self.elements[element_type].append(
[
int(node) for node in
line.values[2:2 + self.element_types[element_type].
number_of_nodes]
[
int(node)
for node in line.values[
2 : 2 + self.element_types[element_type].number_of_nodes
]
]
)


Expand Down Expand Up @@ -159,16 +159,17 @@ def __init__(self, filename):

current_component = None

with open(filename, 'r') as hm_file:
with open(filename) as hm_file:
for line_string in hm_file:
line = HMLine(line_string)

# read node
if line.name == "node":
self.node_ids[int(line.values[0])] =\
len(self.node_coordinates)
self.node_ids[int(line.values[0])] = len(
self.node_coordinates
)
self.node_coordinates.append(
[float(coord) for coord in line.values[1:4]]
[float(coord) for coord in line.values[1:4]]
)

# read component
Expand All @@ -180,13 +181,12 @@ def __init__(self, filename):
elif line.name in HMComponent.element_types:
if not current_component:
raise RuntimeError(
'Encountered element before first '
'component.'
"Encountered element before first " "component."
)
current_component.add_element(line)


def load(fname, element_type=''):
def load(fname, element_type=""):
"""hmascii load.
Parameters
Expand All @@ -211,18 +211,18 @@ def load(fname, element_type=''):
if not element_type:
# which element types occur in the mesh?
element_types_in_model = [
element_type for component in hm_model.components
for element_type in component.elements
element_type
for component in hm_model.components
for element_type in component.elements
]
preferred_element_types = [
element_type
for element_type in HMComponent.element_type_preference
if element_type in element_types_in_model
element_type
for element_type in HMComponent.element_type_preference
if element_type in element_types_in_model
]
if len(preferred_element_types) < 1:
raise RuntimeError(
"Couldn't find any usable element types in "
"model."
"Couldn't find any usable element types in " "model."
)

element_type = preferred_element_types[0]
Expand All @@ -232,8 +232,8 @@ def load(fname, element_type=''):
subelement_type = HMComponent.element_types[element_type].subelement

hm_volume_elements_nonunique = np.ndarray(
shape=(0, HMComponent.element_types[element_type].number_of_nodes),
dtype=int
shape=(0, HMComponent.element_types[element_type].number_of_nodes),
dtype=int,
)

bcs = dict()
Expand All @@ -242,13 +242,13 @@ def load(fname, element_type=''):
for hm_component in hm_model.components:
# can we use all elements?
ignored_element_types = set(hm_component.elements).difference(
{element_type, subelement_type}
{element_type, subelement_type}
)
if len(ignored_element_types) > 0:
utils.log.warning(
f"Component '{hm_component.name}' contains "
f"unkown element types {ignored_element_types}. "
"They will be ignored."
f"Component '{hm_component.name}' contains "
f"unknown element types {ignored_element_types}. "
"They will be ignored."
)

# are there volume elements? append.
Expand All @@ -257,32 +257,31 @@ def load(fname, element_type=''):

# append elements
hm_volume_elements_nonunique = np.concatenate(
(hm_volume_elements_nonunique, elements_in_component)
(hm_volume_elements_nonunique, elements_in_component)
)

# try get bounds
if subelement_type in hm_component.elements and subelement_type in [
'tria3', 'quad4'
"tria3",
"quad4",
]:

bcs[hm_component.name] = (
np.arange(len(elements_in_component))
+ hm_volume_elements_nonunique.shape[0]
np.arange(len(elements_in_component))
+ hm_volume_elements_nonunique.shape[0]
)
else:
utils.log.info("Can`t find any bounds.")

# create unique element list
hm_volume_elements_sorted = np.sort(hm_volume_elements_nonunique, axis=1)
hm_volume_elements_unique_indices = np.unique(
hm_volume_elements_sorted, return_index=True, axis=0
hm_volume_elements_sorted, return_index=True, axis=0
)[1]

# sorting the unique indices isn't necessary, but it might maintain a more
# contiguous element order
volumes = np.squeeze(
hm_volume_elements_nonunique[
hm_volume_elements_unique_indices.sort()]
hm_volume_elements_nonunique[hm_volume_elements_unique_indices.sort()]
)

# create minimal vertex array
Expand All @@ -297,7 +296,8 @@ def load(fname, element_type=''):
node_perm = dict()
for vertex_id, hm_node_id in enumerate(hm_node_indices):
vertices[vertex_id, :] = hm_model.node_coordinates[
hm_model.node_ids[hm_node_id]]
hm_model.node_ids[hm_node_id]
]
node_perm[hm_node_id] = vertex_id

# finalize volumes array
Expand Down

0 comments on commit 8a4cefa

Please sign in to comment.