meshio
meshio copied to clipboard
Support multiple meshes per file
I try to read an abaqus inp mesh of a submarine that be can be found on Internet, that is about 39Mo.
http://dsk.ippt.pan.pl/docs/abaqus/v6.13/books/eif/undex_subbody_h005.inp
After removing trailing spaces and trailing comma from this file, I try to read it with meshio. However, I encounter an error, that does not seem to be related with the mesh, but more with meshio. Here is the log of the error on the fixed input file (no trailing space, and a removed trailing comma line 818313)
import meshio
meshio.__version__
# '2.0.4'
mesh = meshio.read('undex_subbody_h005.inp')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-7-efa787a1d89c> in <module>()
----> 1 mesh = meshio.read('undex_subbody_h005.inp')
c:\program files\python37\lib\site-packages\meshio\helpers.py in read(filename,
file_format)
151 )
152
--> 153 return format_to_reader[file_format].read(filename)
154
155
c:\program files\python37\lib\site-packages\meshio\abaqus_io.py in read(filename
)
94 """
95 with open(filename, "r") as f:
---> 96 out = read_buffer(f)
97 return out
98
c:\program files\python37\lib\site-packages\meshio\abaqus_io.py in read_buffer(f
)
124 points, point_gid = _read_nodes(f, point_gid, points)
125 elif word.startswith("ELEMENT"):
--> 126 cells = _read_cells(f, word, cells)
127 elif word.startswith("NSET"):
128 params_map = get_param_map(word, required_keys=["NSET"])
c:\program files\python37\lib\site-packages\meshio\abaqus_io.py in _read_cells(f
, line0, cells)
181 break
182 data = [int(k) for k in filter(None, line.split(","))]
--> 183 cells[t].append(data[-num_nodes_per_elem:])
184
185 # convert to numpy arrays
AttributeError: 'numpy.ndarray' object has no attribute 'append'
Isn't there a smaller mesh with the same problem?
Also, I'm getting a different error here:
ValueError: invalid literal for int() with base 10: '\n
Read function fails because of multiple identical declarations of *Element. In the file, there are two sections
*Element, type=S3R
The first one is converted to a numpy array, then one can not append to a numpy array.
I am testing this to fix the bug (if one can have multiple sections with identical keys)
def _read_cells(f, line0, cells):
sline = line0.split(",")[1:]
etype_sline = sline[0]
assert "TYPE" in etype_sline, etype_sline
etype = etype_sline.split("=")[1].strip()
if etype not in abaqus_to_meshio_type:
msg = "Element type not available: " + etype
raise RuntimeError(msg)
t = abaqus_to_meshio_type[etype]
num_nodes_per_elem = num_nodes_per_cell[t]
current_cells = []
while True:
last_pos = f.tell()
line = f.readline()
if line.startswith("*"):
break
data = [int(k) for k in filter(None, line.split(","))]
current_cells.append(data[-num_nodes_per_elem:])
# convert to numpy arrays
# Subtract one to account for the fact that python indices are
# 0-based.
current_cells = numpy.array(current_cells, dtype=int)
if t in cells:
cells[t] = numpy.concatenate((cells[t], current_cells), axis=0)
else:
cells[t] = current_cells
f.seek(last_pos)
return cells
I just fixed some things about the abaqus reader in #269; it should now be much faster as well.
One remaining problem is that meshio doesn't support referencing sets yet (like abaqus does); the same goes for multiple meshes per file (or "Instances", as abaqus calls it).
Thanks @nschloe , I have tested the new code with undex_subbody_h005.inp file. It returns the following error: I don't know if the input file does not respect inp format, or if the python script is too strict...
import meshio
mesh = meshio.read('undex_subbody_h005.inp')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-65aa98e1854a> in <module>()
----> 1 mesh = meshio.read('undex_subbody_h005.inp')
~/meshio/meshio/helpers.py in read(filename, file_format)
151 )
152
--> 153 return format_to_reader[file_format].read(filename)
154
155
~/meshio/meshio/abaqus_io.py in read(filename)
91 """
92 with open(filename, "r") as f:
---> 93 out = read_buffer(f)
94 return out
95
~/meshio/meshio/abaqus_io.py in read_buffer(f)
123 elif word.startswith("NSET"):
124 params_map = get_param_map(word, required_keys=["NSET"])
--> 125 setids = read_set(f, params_map)
126 name = params_map["NSET"]
127 if name not in nsets:
~/meshio/meshio/abaqus_io.py in read_set(f, params_map)
236 if line.startswith("*"):
237 break
--> 238 set_ids += [int(k) for k in line.strip().strip(",").split(",")]
239 f.seek(last_pos)
240
~/meshio/meshio/abaqus_io.py in <listcomp>(.0)
236 if line.startswith("*"):
237 break
--> 238 set_ids += [int(k) for k in line.strip().strip(",").split(",")]
239 f.seek(last_pos)
240
ValueError: invalid literal for int() with base 10: 'subbody1'
I don't know if the input file does not respect inp format, or if the python script is too strict...
Like I said, meshio doesn't support multiple meshes per file yet, which the Instance blocks in the abaqus file appear to be. Hence the error.
Ok, sorry for bothering. I close the issue for time being.
Let's leave it open, it's a bug after all! :)
I'll add XDMF to the list of formats supporting multiple meshes. #568 #622