Skip to content

Commit

Permalink
fix: read physical groups from msh file
Browse files Browse the repository at this point in the history
  • Loading branch information
yexiang1992 committed Dec 11, 2024
1 parent 9ac0ec2 commit 2c84acd
Showing 1 changed file with 42 additions and 17 deletions.
59 changes: 42 additions & 17 deletions opstool/pre/_read_gmsh.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import re
import gmsh
import numpy as np
import openseespy.opensees as ops
Expand Down Expand Up @@ -35,12 +36,14 @@ def __init__(self, ndm: int = 3, ndf: int = 3):
self.out_file = None
self.out_type = None

def set_output_file(self, filename: str = "src.tcl"):
def set_output_file(self, filename: str = "src.tcl", encoding: str = "utf-8"):
"""
Parameters:
------------
filename: str, default = "src.tcl".
The output file-path-name must end with ``.tcl`` or ``.py``.
encoding: str, default = "utf-8".
The file encoding.
"""
self.out_file = filename
if filename.endswith(".tcl"):
Expand All @@ -49,7 +52,7 @@ def set_output_file(self, filename: str = "src.tcl"):
self.out_type = "py"
else:
raise ValueError("output_filename must end with .tcl or .py!")
with open(self.out_file, "w+") as outf:
with open(self.out_file, "w+", encoding=encoding) as outf:
outf.write(f"# This file was created by {self.__class__.__name__}\n\n")
if self.out_type == "py":
outf.write("import openseespy.opensees as ops\n\n")
Expand All @@ -61,7 +64,12 @@ def set_output_file(self, filename: str = "src.tcl"):
outf.write("wipe\n")
outf.write(f"model basic -ndm {self.ndm} -ndf {self.ndf}\n\n")

def read_gmsh_file(self, file_path: str, print_info: bool = True):
def read_gmsh_file(
self,
file_path: str,
encoding: str = "utf-8",
print_info: bool = True
):
"""
Read an ``.msh`` file generated by ``GMSH``.
Expand All @@ -74,10 +82,12 @@ def read_gmsh_file(self, file_path: str, print_info: bool = True):
-----------
file_path: str
the file path.
encoding: str, default='utf-8'
The file encoding.
print_info: bool, default=True
Print info.
"""
with open(file_path) as inf:
with open(file_path, encoding=encoding) as inf:
lines = [ln.strip() for ln in inf.readlines()]
# Remove comments
lines = [ln for ln in lines if not ln.startswith("**")]
Expand All @@ -92,7 +102,7 @@ def read_gmsh_file(self, file_path: str, print_info: bool = True):
physical_idx.append(lines.index("$PhysicalNames"))
physical_idx.append(lines.index("$EndPhysicalNames"))

# key: physical_tag, value: physical_name
# key: (dim, physical_tag), value: physical_name
physical_tag_name_map = _retrieve_physical_groups(lines, physical_idx)
self.gmsh_entities, self.gmsh_physical_groups = _retrieve_entities(
lines, entities_idx, physical_tag_name_map
Expand Down Expand Up @@ -668,21 +678,32 @@ def _get_boundary_dim_tags(boundary_dimtags, dim_entity_tags, entites):
# if eetag[0] > 0:
# _get_boundary_dim_tags(boundary_dimtags, [eetag])
def _retrieve_physical_groups(lines, physical_idx):
pattern = r'(\d+)\s+(\d+)\s+"(.*)"'
tag_name_map = dict()
if len(physical_idx) > 0:
idx = physical_idx[0] + 1
num = int(lines(idx))
print(f"Info:: {num} Physical Groups.")
num = int(lines[idx])
print(f"Info:: {num} Physical Names.")
for i in range(num):
idx += i + 1
contents = [int(data) for data in lines[idx].split(" ")]
# dim = contents[0]
tag = contents[1]
name = contents[2]
tag_name_map[tag] = name
idx += 1
match = re.match(pattern, lines[idx])
if match:
dim = int(match.group(1))
tag = int(match.group(2))
name = match.group(3)
else:
raise RuntimeError("Not all physical groups have names set!")
tag_name_map[(dim, tag)] = name
return tag_name_map


def _check_physical_tag_name_map(key, physical_tag_name_map):
if key not in physical_tag_name_map.keys():
raise KeyError(
f"(dim={key[0]}, physical tag={key[1]}) has no physical name set!"
)


def _retrieve_entities(lines, entities_idx, physical_tag_name_map):
entities = defaultdict(dict)
gmsh_physical_groups = defaultdict(list)
Expand All @@ -698,7 +719,8 @@ def _retrieve_entities(lines, entities_idx, physical_tag_name_map):
entities[(0, tag)]["numPhysicalTags"] = int(contents[4])
physical_tags = [int(contents[5 + iii]) for iii in range(int(contents[4]))]
for ptag in physical_tags:
pname = physical_tag_name_map[ptag]
_check_physical_tag_name_map((0, ptag), physical_tag_name_map)
pname = physical_tag_name_map[(0, ptag)]
gmsh_physical_groups[pname].append((0, tag))
entities[(0, tag)]["physicalTags"] = physical_tags
entities[(0, tag)]["numBound"] = 0
Expand All @@ -713,7 +735,8 @@ def _retrieve_entities(lines, entities_idx, physical_tag_name_map):
entities[(1, tag)]["numPhysicalTags"] = int(contents[7])
physical_tags = [int(contents[8 + iii]) for iii in range(int(contents[7]))]
for ptag in physical_tags:
pname = physical_tag_name_map[ptag]
_check_physical_tag_name_map((1, ptag), physical_tag_name_map)
pname = physical_tag_name_map[(1, ptag)]
gmsh_physical_groups[pname].append((1, tag))
entities[(1, tag)]["physicalTags"] = physical_tags
numBounds = int(contents[8 + int(contents[7])])
Expand All @@ -732,7 +755,8 @@ def _retrieve_entities(lines, entities_idx, physical_tag_name_map):
entities[(2, tag)]["numPhysicalTags"] = int(contents[7])
physical_tags = [int(contents[8 + iii]) for iii in range(int(contents[7]))]
for ptag in physical_tags:
pname = physical_tag_name_map[ptag]
_check_physical_tag_name_map((2, ptag), physical_tag_name_map)
pname = physical_tag_name_map[(2, ptag)]
gmsh_physical_groups[pname].append((2, tag))
entities[(2, tag)]["physicalTags"] = physical_tags
numBounds = int(contents[8 + int(contents[7])])
Expand All @@ -751,7 +775,8 @@ def _retrieve_entities(lines, entities_idx, physical_tag_name_map):
entities[(3, tag)]["numPhysicalTags"] = int(contents[7])
physical_tags = [int(contents[8 + iii]) for iii in range(int(contents[7]))]
for ptag in physical_tags:
pname = physical_tag_name_map[ptag]
_check_physical_tag_name_map((3, ptag), physical_tag_name_map)
pname = physical_tag_name_map[(3, ptag)]
gmsh_physical_groups[pname].append((3, tag))
entities[(3, tag)]["physicalTags"] = physical_tags
numBounds = int(contents[8 + int(contents[7])])
Expand Down

0 comments on commit 2c84acd

Please sign in to comment.