Source code for meshConversion

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 extract_current_face_nodes(key, grouped_elements, nodes): """ 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. """ first_group = grouped_elements[key] # Extract the first 3 elements from each row first_three_elements = first_group[:, :2] # Flatten the array flattened_elements = first_three_elements.flatten() # Remove duplicates unique_elements = np.unique(flattened_elements) # Shift the positions by 1 shifted_indices = unique_elements-1 current_nodes = nodes[shifted_indices] return current_nodes
[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