This repository serve as a backup for my Maxwell-TD code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

245 lines
7.6 KiB

import numpy as np
from collections import defaultdict
import meshio
import os
import shutil
def parse_node_file(lines):
"""
Parses the `.node` file. Each node spans two lines: a header and a line with x y z coordinates.
"""
num_nodes = int(lines[1].strip())
totalNodes = []
for i in range(num_nodes):
coords_line = lines[3 + i * 2].strip()
coords = list(map(float, coords_line.split()))
totalNodes.append(coords)
return np.array(totalNodes)
def parse_tetra_file(lines):
"""
Parses the `.tetra` file:
- First line: number of tets
- Even lines: [flag node0 node1 node2 node3]
- Odd lines: face BCs (ignored)
Returns: list of [n0, n1, n2, n3]
"""
num_tets = int(lines[0].strip())
tetra_data = []
material_data = []
for i in range(num_tets):
parts = lines[1 + 2 * i].strip().split()
if len(parts) != 5:
continue
mat, n0, n1, n2, n3 = map(int, parts)
tetra_data.append([n0, n1, n2, n3])
material_data.append(mat)
return tetra_data, material_data
def read_group_ids_from_regular(filename):
"""
Reads group IDs from `.regular` file: one integer per line corresponding to a tetrahedron.
"""
with open(filename, 'r') as f:
lines = f.readlines()
group_ids = np.array([int(line.strip()) for line in lines if line.strip().isdigit()], dtype=np.int32)
group_ids = group_ids[1::]
return group_ids
def export_vtu_from_node_tetra(filename, totalNodes, tetra_data):
"""
Exports a VTU file without group IDs.
"""
tetra_data = np.array(tetra_data, dtype=np.int32)
points = totalNodes.astype(np.float64)
cells = [("tetra", tetra_data)]
mesh = meshio.Mesh(points=points, cells=cells)
mesh.write(filename, file_format="vtu")
print(f"✅ Exported VTU: {filename}")
import numpy as np
import meshio
def export_vtu_per_groups(base_filename, totalNodes, tetra_data, group_ids):
"""
Exports one VTU file per unique group ID.
Parameters:
- base_filename: output name prefix (e.g., "grouped_mesh" → creates grouped_mesh_group1.vtu, etc.)
- totalNodes: (N, 3) array of node coordinates
- tetra_data: list of [n0, n1, n2, n3] tetrahedra
- group_ids: array of group IDs, one per tetrahedron
"""
tetra_data = np.array(tetra_data, dtype=np.int32)
group_ids = np.array(group_ids, dtype=np.int32)
unique_groups = np.unique(group_ids)
print(f"🔹 Found {len(unique_groups)} unique groups: {unique_groups}")
for gid in unique_groups:
if gid == 0:
continue # Optional: skip ungrouped tets (ID = 0)
mask = group_ids == gid
group_tets = tetra_data[mask]
if len(group_tets) == 0:
continue
# Find the unique nodes used in this group
used_nodes = np.unique(group_tets)
node_id_map = {old: new for new, old in enumerate(used_nodes)}
# Remap node indices
remapped_tets = np.array([[node_id_map[n] for n in tet] for tet in group_tets])
remapped_nodes = totalNodes[used_nodes]
# Create and write mesh
mesh = meshio.Mesh(
points=remapped_nodes.astype(np.float64),
cells=[("tetra", remapped_tets)],
cell_data={"group_id": [np.full(len(remapped_tets), gid, dtype=np.int32)]}
)
outname = f"{base_filename}_group{gid}.vtu"
mesh.write(outname, file_format="vtu")
print(f"✅ Exported: {outname}")
def export_vtu_per_material(base_filename, totalNodes, tetra_data, group_ids):
"""
Exports one VTU file per unique group ID.
Parameters:
- base_filename: output name prefix (e.g., "grouped_mesh" → creates grouped_mesh_group1.vtu, etc.)
- totalNodes: (N, 3) array of node coordinates
- tetra_data: list of [n0, n1, n2, n3] tetrahedra
- group_ids: array of group IDs, one per tetrahedron
"""
tetra_data = np.array(tetra_data, dtype=np.int32)
group_ids = np.array(group_ids, dtype=np.int32)
unique_groups = np.unique(group_ids)
print(f"🔹 Found {len(unique_groups)} unique groups: {unique_groups}")
for gid in unique_groups:
mask = group_ids == gid
group_tets = tetra_data[mask]
if len(group_tets) == 0:
continue
# Find the unique nodes used in this group
used_nodes = np.unique(group_tets)
node_id_map = {old: new for new, old in enumerate(used_nodes)}
# Remap node indices
remapped_tets = np.array([[node_id_map[n] for n in tet] for tet in group_tets])
remapped_nodes = totalNodes[used_nodes]
# Create and write mesh
mesh = meshio.Mesh(
points=remapped_nodes.astype(np.float64),
cells=[("tetra", remapped_tets)],
cell_data={"group_id": [np.full(len(remapped_tets), gid, dtype=np.int32)]}
)
outname = f"{base_filename}_group{gid}.vtu"
mesh.write(outname, file_format="vtu")
print(f"✅ Exported: {outname}")
def export_vtu_per_group(base_filename, totalNodes, tetra_data, group_array, target_groups):
"""
Exports one .vtu file per group ID specified in target_groups.
Parameters:
- base_filename: base name for output (e.g., "grouped_output")
- totalNodes: (N, 3) array of node coordinates
- tetra_data: list of [n0, n1, n2, n3] tetrahedra
- group_array: array of group IDs, same length as tetra_data
- target_groups: list of group IDs to export
"""
group_array = np.asarray(group_array)
tetra_data = np.asarray(tetra_data)
for group_id in target_groups:
mask = group_array == group_id
if not np.any(mask):
print(f" Group {group_id} not found.")
continue
tets = tetra_data[mask]
used_nodes = np.unique(tets)
node_id_map = {old: new for new, old in enumerate(used_nodes)}
remapped_tets = np.array([[node_id_map[v] for v in tet] for tet in tets])
remapped_nodes = totalNodes[used_nodes]
mesh = meshio.Mesh(
points=remapped_nodes.astype(np.float64),
cells=[("tetra", remapped_tets)],
cell_data={"group_id": [np.full(len(remapped_tets), group_id, dtype=np.int32)]}
)
outname = f"{base_filename}_group{group_id}.vtu"
mesh.write(outname, file_format="vtu")
print(f"✅ Exported group {group_id}: {outname}")
# ======= MAIN =======
name = "PW" # base filename
# Load mesh
with open(f"{name}.node") as f:
node_lines = f.readlines()
with open(f"{name}.tetra") as f:
tetra_lines = f.readlines()
totalNodes = parse_node_file(node_lines)
tetra_data,material_data = parse_tetra_file(tetra_lines)
# Load group IDs from .regular file
group_array = read_group_ids_from_regular(f"{name}.regular")
# Export full mesh without groups
export_vtu_from_node_tetra(f"{name}.vtu", totalNodes, tetra_data)
print("🔎 Number of tetrahedra from .tetra file:", len(tetra_data))
print("🔎 Number of group IDs from .regular file:", len(group_array))
# Export grouped mesh with group_id per tet
print(group_array)
export_vtu_per_groups("grouped_output", totalNodes, tetra_data, group_array)
export_vtu_per_group("grouped_output", totalNodes, tetra_data, group_array, [0])
export_vtu_per_material("material", totalNodes, tetra_data, material_data)
# ======= ORGANIZE OUTPUT =======
out_dir = "VTU_files"
os.makedirs(out_dir, exist_ok=True)
for file in os.listdir("."):
if file.endswith(".vtu"):
shutil.move(file, os.path.join(out_dir, file))
print(f"📂 All .vtu files have been moved to: {out_dir}/")