Moved away from heavy handed "bulk_str = f.read()" and instead opted for creating new generator object for included file while storing existing generator in temp variable.
"""
I/O for Abaqus inp files.
"""
-import io
import pathlib
-import re
import numpy
@@ -96,30 +94,6 @@ abaqus_to_meshio_type = {
meshio_to_abaqus_type = {v: k for k, v in abaqus_to_meshio_type.items()}
-def read_w_includes(inp_path):
- re_in = re.compile(
- r"\*Include,\s*input=(.*?)$", re.IGNORECASE | re.MULTILINE | re.DOTALL
- )
- bulk_repl = dict()
- with open_file(inp_path, "r") as f:
- bulk_str = f.read()
-
- for m in re_in.finditer(bulk_str):
- search_key = m.group(0)
- incl_ref = m.group(1).replace("\\", "/")
- # The include ref can be absolute or relative to .inp file. Will check for both
- if pathlib.Path(incl_ref).exists() is False:
- cd = pathlib.Path(inp_path).parents[0]
- incl_ref = cd / incl_ref
- with open(pathlib.Path(incl_ref).absolute(), "r") as d:
- bulk_repl[search_key] = d.read()
-
- for key, val in bulk_repl.items():
- bulk_str = bulk_str.replace(key, val)
-
- return read_buffer(io.StringIO(bulk_str))
-
-
def read(filename):
"""Reads a Abaqus inp file."""
with open_file(filename, "r") as f:
@@ -139,9 +113,19 @@ def read_buffer(f):
cell_data = {}
point_data = {}
+ parent_file_gen = None
+
line = f.readline()
while True:
if not line: # EOF
+ if parent_file_gen is not None:
+ f.close()
+ f = parent_file_gen
+ parent_file_gen = None
+ line = f.readline()
+ if not line:
+ break
+ else:
break
# Comments
@@ -194,7 +178,16 @@ def read_buffer(f):
else:
raise ReadError(f"Unknown cell set '{set_name}'")
elif keyword == "INCLUDE":
- return read_w_includes(f.name)
+ # Get absolute path to referred input file
+ incl_ref = line.lower().split("input=")[-1].rstrip().replace("\\", "/")
+ if pathlib.Path(incl_ref).exists() is False:
+ cd = pathlib.Path(f.name).parents[0]
+ incl_ref = cd / incl_ref
+ # Store current generator in temp object parent_file_gen
+ parent_file_gen = f
+ f = open(pathlib.Path(incl_ref).absolute(), "r")
+ line = f.readline()
+ # return read_w_includes(f.name)
else:
# There are just too many Abaqus keywords to explicitly skip them.
line = f.readline()
