Files
Dean Huang e9bd61b56f start
2025-12-08 10:11:12 +08:00

203 lines
6.2 KiB
Python

from devsim import (
add_gmsh_contact,
add_gmsh_interface,
add_gmsh_region,
create_device,
create_gmsh_mesh,
finalize_mesh,
get_contact_list,
get_element_node_list,
get_interface_list,
get_node_model_values,
get_region_list,
write_devices,
)
import itertools
print("coordinates")
coordinates = []
for i in range(0, 11):
coordinates.extend([float(i), 0.0, 0.0])
print(coordinates)
print()
print("elements")
elements = []
for i in range(0, 5):
# line type, physical region 0
x = [1, 0, i, i + 1]
print(x)
elements.extend(x)
for i in range(5, 10):
# line type, physical region 1
x = [1, 1, i, i + 1]
print(x)
elements.extend([1, 1, i, i + 1])
# points for boundary conditions
elements.extend([0, 2, 0])
print(elements[-3:])
elements.extend([0, 3, 10])
print(elements[-3:])
elements.extend([0, 4, 5])
print(elements[-3:])
print()
print("physical_names")
physical_names = ["top", "bot", "top_contact", "bot_contact", "top_bot_interface"]
print(physical_names)
print()
create_gmsh_mesh(
mesh="toy",
coordinates=coordinates,
physical_names=physical_names,
elements=elements,
)
add_gmsh_region(mesh="toy", gmsh_name="top", region="top", material="silicon")
add_gmsh_region(mesh="toy", gmsh_name="bot", region="bot", material="silicon")
add_gmsh_contact(
mesh="toy",
gmsh_name="top_contact",
name="top_contact",
region="top",
material="metal",
)
add_gmsh_contact(
mesh="toy",
gmsh_name="bot_contact",
name="bot_contact",
region="bot",
material="metal",
)
add_gmsh_interface(
mesh="toy",
gmsh_name="top_bot_interface",
name="top_bot_interface",
region0="top",
region1="bot",
)
finalize_mesh(mesh="toy")
create_device(mesh="toy", device="toy")
write_devices(device="toy", file="pythonmesh1d.msh")
class MeshWriter:
def __init__(self, device):
# gets the mesh input for existing devices
self.device = device
self.physical_names = []
self.elements = []
self.coordinates = []
self.coordinates_xyz = []
self.region_to_coordinate_indexes = {}
self.name_to_physical_index = {}
def get_element_list(self, shapes, physical_index, region_coordinate_indexes):
# Element Type (float)
# 0 node
# 1 edge
# 2 triangle
# 3 tetrahedron
element_list = []
for shape in shapes:
element_list.append(len(shape) - 1)
element_list.append(physical_index)
element_list.extend([region_coordinate_indexes[i] for i in shape])
return element_list
def get_global_coordinates(self):
# this is the global list of coordinates
for r in get_region_list(device=self.device):
region_coordinates = [
int(x)
for x in get_node_model_values(
device=self.device, region=r, name="coordinate_index"
)
]
self.region_to_coordinate_indexes[r] = region_coordinates
# expand global coordinate list as necessary
clen = max(region_coordinates) + 1
if clen > len(self.coordinates_xyz):
self.coordinates_xyz.extend([None] * (clen - len(self.coordinates_xyz)))
node_positions = zip(
get_node_model_values(device=self.device, region=r, name="x"),
get_node_model_values(device=self.device, region=r, name="y"),
get_node_model_values(device=self.device, region=r, name="z"),
)
for i, p in enumerate(node_positions):
self.coordinates_xyz[region_coordinates[i]] = p
self.coordinates = list(itertools.chain.from_iterable(self.coordinates_xyz))
def get_elements(self):
for r in get_region_list(device=self.device):
rtc = self.region_to_coordinate_indexes[r]
physical_index = self.name_to_physical_index[r]
elist = self.get_element_list(
get_element_node_list(device=self.device, region=r), physical_index, rtc
)
self.elements.extend(elist)
for c in get_contact_list(device=self.device):
r = get_region_list(device=self.device, contact=c)[0]
rtc = self.region_to_coordinate_indexes[r]
physical_index = self.name_to_physical_index[c]
elist = self.get_element_list(
get_element_node_list(device=self.device, region=r, contact=c),
physical_index,
rtc,
)
self.elements.extend(elist)
# warning, this will not work for the special periodic boundary condition
for i in get_interface_list(device=self.device):
elists = []
for r in get_region_list(device=self.device, interface=i):
rtc = self.region_to_coordinate_indexes[r]
physical_index = self.name_to_physical_index[i]
elist = self.get_element_list(
get_element_node_list(device=self.device, region=r, interface=i),
physical_index,
rtc,
)
elists.append(elist)
if elists[0] != elists[1]:
raise RuntimeError(
f"Error processing interface {i}. If you are using the periodic interface boundary condition, then please contact support for modifying script."
)
self.elements.extend(elists[0])
def populate_physical_names(self):
def add_name(name):
if name in self.name_to_physical_index:
raise RuntimeError(f"Cannot use name {name} twice")
self.physical_names.append(name)
self.name_to_physical_index[name] = len(self.physical_names) - 1
for r in get_region_list(device=self.device):
add_name(r)
for c in get_contact_list(device=self.device):
add_name(c)
for i in get_interface_list(device=self.device):
add_name(i)
def process_mesh(self):
self.populate_physical_names()
self.get_global_coordinates()
self.get_elements()
mw = MeshWriter(device="toy")
mw.process_mesh()
print(mw.physical_names)
print(mw.coordinates)
print(mw.elements)