import os
import sys
import src.helpers.meshimporter as m
import src.helpers.meshwriter as w
import tkinter as tk
from tkinter import filedialog
import numpy as np
import h5py
import json
[docs]
def main(argv):
"""
Main function to process a mesh file and export its properties.
Args:
argv (list): List of command-line arguments.
- If no arguments are provided, a file dialog is opened to select the mesh file.
- If one argument is provided, it is treated as the path to the mesh file.
- If two arguments are provided, the first is the path to the mesh file,
and the second is the export path.
Functionality:
- Reads a mesh file in either UTF-8 or ISO-8859-1 encoding.
- Calls helper functions to find mesh delimiters and write mesh information to a specified export path.
- If no file path is provided via the command-line arguments, a file selection dialog is opened.
Raises:
SystemExit: Exits the program if more than two arguments are provided.
"""
currentPath = os.path.dirname(__file__)
if len(argv) < 1:
# create a root window
root = tk.Tk()
root.withdraw()
# open the file dialog box
meshToRead = filedialog.askopenfilename()
meshToExportPath=os.path.dirname(meshToRead)
elif len(argv)==1:
# read mesh path
meshToRead = argv[0]
meshToExportPath=os.path.dirname(meshToRead)
elif len(argv)==2:
# read mesh path and output path
meshToRead = argv[0]
meshToExportPath = argv[1]
else:
exit(1)
try:
# Try reading with UTF-8 first
with open(meshToRead, 'r', encoding='utf-8', errors='replace') as f:
lines = f.readlines()
except UnicodeDecodeError:
# If UTF-8 fails, try ISO-8859-1 (Latin-1)
with open(meshToRead, 'r', encoding='ISO-8859-1') as f:
lines = f.readlines()
ids=m.findDelimiter(lines)
#for k in ids["LastElementLine"]:
# print("Minus:")
# print(lines[k-1])
# print("Actual:")
# print(lines[k])
#for lin in ids:
# print mesh properties
# print(lin+": "+str(ids[lin]))
# write .txt files
w.writeMesh(ids,lines,meshToExportPath)
if __name__ == "__main__":
main(sys.argv[1:])
[docs]
def estimate_radius_by_sections(points, num_sections=50):
"""
Extracts and returns the node coordinates of the current face of the mesh element.
Args:
key (int): The identifier key for the group of mesh elements.
grouped_elements (dict): Dictionary where keys are element IDs and values are arrays of grouped mesh elements.
nodes (ndarray): Array containing the coordinates of the mesh nodes.
Returns:
ndarray: The node coordinates corresponding to the extracted face,
after removing duplicates and shifting positions by 1.
"""
# Get the min and max z values to define the sections
z_min, z_max = np.min(points[:, 2]), np.max(points[:, 2])
z_range = z_max - z_min
section_height = z_range / num_sections
radii = []
for i in range(num_sections):
# Define the bounds of the current section
z_lower = z_min + i * section_height
z_upper = z_min + (i + 1) * section_height
# Select points within this section
section_points = points[(points[:, 2] >= z_lower) & (points[:, 2] < z_upper)]
if len(section_points) == 0:
continue
# Calculate the mean center of the points in the xy-plane
xy_center = np.mean(section_points[:, :2], axis=0)
# Calculate the distance of each point to the center (radius)
distances = np.linalg.norm(section_points[:, :2] - xy_center, axis=1)
# Calculate the mean radius of this section
mean_radius = np.mean(distances)
radii.append(mean_radius)
# Calculate the overall mean radius across all sections
overall_mean_radius = np.mean(radii)
return overall_mean_radius
[docs]
def classify_surfaces(h5_file_path):
"""
Classifies and identifies the surfaces (top, bottom, internal, and external) of a mesh structure
based on node information from an HDF5 file.
Args:
h5_file_path (str): The file path to the HDF5 file containing mesh data.
Functionality:
- Reads the mesh data from the HDF5 file, including node coordinates and element information.
- Groups mesh elements by ID.
- Identifies the top and bottom surfaces based on the z-coordinate of the nodes.
- Calculates the radius of each remaining surface and classifies them as internal or external.
- Saves the surface classification in a JSON file.
Returns:
None
"""
try:
with h5py.File(h5_file_path, 'r') as h5file:
# Read the ID_T2 and Elements_T2 datasets
id_t2 = h5file['/ID_T2'][:]
nodes = h5file['/nodes'][:]
elements_t2 = h5file['/Elements_T2'][:]
elements_o2 = h5file['/Elements_O2'][:]
print(" ")
print("Total # of elements: ", len(elements_o2))
print(" ")
# Create a dictionary to group elements by their ID
grouped_elements = {}
for i, id_values in enumerate(id_t2):
id_value = id_values[0]
if id_value in grouped_elements:
grouped_elements[id_value].append(elements_t2[i])
else:
grouped_elements[id_value] = [elements_t2[i]]
# Convert lists to numpy arrays for easier handling later
for key in grouped_elements:
grouped_elements[key] = np.array(grouped_elements[key])
# Extract the first group of elements
surface = {}
keys = list(grouped_elements.keys())
nonTopNorBottom = []
for key in keys:
#print(key)
min_z = np.min(nodes[:, 2])
max_z = np.max(nodes[:, 2])
#print(min_z)
#print(max_z)
current_nodes = extract_current_face_nodes(key, grouped_elements, nodes)
#print(np.min(current_nodes[:, 2]))
#print(np.max(current_nodes[:, 2]))
if abs(np.mean(current_nodes[:, 2]) - min_z)<1e-6:
surface['bottom'] = int(key)
#print('The elements are at the bottom of the mesh')
elif abs(np.mean(current_nodes[:, 2] - max_z))<1e-6:
#print('The elements are at the top of the mesh')
surface['top'] = int(key)
else:
#print('The elements are not at the top or bottom of the mesh')
nonTopNorBottom.append(key)
# Calculate the radius for each surface in nonTopNorBottom
surface_radii = {}
for key in nonTopNorBottom:
#print(f'Processing key: {key}')
current_nodes = extract_current_face_nodes(key, grouped_elements, nodes)
radius = estimate_radius_by_sections(current_nodes, num_sections=50)
#print(f'Estimated radius for ID {key}: {radius}')
surface_radii[key] = radius
# Determine the internal and external surfaces
internal_surface_key = min(surface_radii, key=surface_radii.get)
external_surface_key = max(surface_radii, key=surface_radii.get)
#print(f'Internal surface ID: {internal_surface_key}, Radius: {surface_radii[internal_surface_key]}')
#print(f'External surface ID: {external_surface_key}, Radius: {surface_radii[external_surface_key]}')
surface['internal'] = int(internal_surface_key)
surface['external'] = int(external_surface_key)
print("Identified surface tag as: " , surface)
directory = os.path.dirname(h5_file_path)
json_file_path = os.path.join(directory,'surfaces.json')
# Save the dictionary as a JSON file
with open(json_file_path, 'w') as json_file:
json.dump(surface, json_file, indent=4)
except Exception as e:
print(f"An error occurred: {e}")
return