Skip to content

Commit

Permalink
Merge pull request #79 from nico-arnold/correct2412
Browse files Browse the repository at this point in the history
Correct dataset 2412
  • Loading branch information
jankoslavic committed Sep 25, 2023
2 parents bfc58a4 + c299bf3 commit b600e0f
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 43 deletions.
123 changes: 86 additions & 37 deletions pyuff/datasets/dataset_2412.py
Original file line number Diff line number Diff line change
@@ -1,62 +1,95 @@
import numpy as np
import itertools

from ..tools import _opt_fields, _parse_header_line, check_dict_for_none

def _write2412(fh, dset):
try:
elt_type_dict = {'triangle': 3, 'quad': 4}
fh.write('%6i\n%6i%74s\n' % (-1, 2412, ' '))
for elt_type in dset:
if elt_type == "type":
pass
else:
for i in range(len(dset[elt_type]['element_nums'])):
fh.write('%10i%10i%10i%10i%10i%10i\n' % (
dset[elt_type]['element_nums'][i],
dset[elt_type]['fe_descriptor'][i],
dset[elt_type]['phys_table'][i],
dset[elt_type]['mat_table'][i],
dset[elt_type]['color'][i],
elt_type_dict[elt_type],
for el_type in dset:
if type(el_type) is not int:
# Skip 'type', 'triangle' and 'quad' indices
continue
for elem in dset[el_type]:
fh.write('%10i%10i%10i%10i%10i%10i\n' % (
elem['element_nums'],
elem['fe_descriptor'],
elem['phys_table'],
elem['mat_table'],
elem['color'],
elem['num_nodes'],
))
if elem['fe_descriptor'] == 11:
# Rods have to be written in 3 lines - ad additional line here
fh.write('%10i%10i%10i\n' % (
elem['beam_orientation'],
elem['beam_foreend_cross'],
elem['beam_aftend_cross']
))
for ii in range(elt_type_dict[elt_type]):
fh.write('%10i' % dset[elt_type]['nodes_nums'][i][ii])
fh.write('\n')
for ii in elem['nodes_nums']:
fh.write('%10i' % ii)
fh.write('\n')
fh.write('%6i\n' % -1)

except:
raise Exception('Error writing data-set #2412')


def _extract2412(block_data):
"""Extract element data - data-set 2412."""
dset = {'type': 2412}
# Define dictionary of possible elements types
# Only 2D non-quadratic elements are supported
elt_type_dict = {'3': 'triangle', '4': 'quad'}
# Define dictionary of possible elements types for legacy interface
elt_type_dict = {41: 'triangle', 44: 'quad'}
# Elements that are seen as rods and read as 3 lines
rods_dict = {11, 21, 22, 23, 24}

# Read data
try:
split_data = block_data.splitlines()
split_data = [a.split() for a in split_data][2:]
# Extract Record 1
rec1 = np.array(split_data[::2], dtype=int)
# Extract Record 2
rec2 = split_data[1::2]
# Look for the different types of elements stored in the dataset
elts_types = list(set(rec1[:,5]))
for elt_type in elts_types:
ind = np.where(np.array(rec1[:,5]) == elt_type)[0]

# Extract Records
i = 0
while i < len(split_data):
dict_tmp = dict()
dict_tmp['element_nums'] = rec1[ind,0].copy()
dict_tmp['fe_descriptor'] = rec1[ind,1].copy()
dict_tmp['phys_table'] = rec1[ind,2].copy()
dict_tmp['mat_table'] = rec1[ind,3].copy()
dict_tmp['color'] = rec1[ind,4].copy()
dict_tmp['nodes_nums'] = np.array([rec2[i] for i in ind], dtype=int).copy().reshape((-1,elt_type))
dset[elt_type_dict[str(elt_type)]] = dict_tmp
line = split_data[i]
dict_tmp['element_nums'] = int(line[0])
dict_tmp['fe_descriptor'] = int(line[1])
dict_tmp['phys_table'] = int(line[2])
dict_tmp['mat_table'] = int(line[3])
dict_tmp['color'] = int(line[4])
dict_tmp['num_nodes'] = int(line[5])
if dict_tmp['fe_descriptor'] in rods_dict:
# element is a rod and covers 3 lines
dict_tmp['beam_orientation'] = int(split_data[i+1][0])
dict_tmp['beam_foreend_cross'] = int(split_data[i + 1][1])
dict_tmp['beam_aftend_cross'] = int(split_data[i + 1][2])
dict_tmp['nodes_nums'] = [int(e) for e in split_data[i+2]]
i += 3
else:
# element is no rod and covers 2 lines
dict_tmp['nodes_nums'] = [int(e) for e in split_data[i+1]]
i += 2
desc = dict_tmp['fe_descriptor']
if not desc in dset:
dset[desc] = []
dset[desc].append(dict_tmp)
for num, name in elt_type_dict.items():
# if we have one of the keys that are enabled for the legacy interface, add everything for that here
if num in dset.keys():
dset[name] = {
'element_nums': [e['element_nums'] for e in dset[num]],
'fe_descriptor': [e['fe_descriptor'] for e in dset[num]],
'phys_table': [e['phys_table'] for e in dset[num]],
'mat_table': [e['mat_table'] for e in dset[num]],
'color': [e['color'] for e in dset[num]],
'num_nodes': [e['num_nodes'] for e in dset[num]],
'nodes_nums': [e['nodes_nums'] for e in dset[num]],
}

return dset

except:
raise Exception('Error reading data-set #2412')
return dset


def prepare_2412(
Expand All @@ -67,6 +100,9 @@ def prepare_2412(
color=None,
num_nodes=None,
nodes_nums=None,
beam_orientation=None,
beam_foreend_cross=None,
beam_aftend_cross=None,
return_full_dict=False):
"""Name: Elements
Expand All @@ -78,7 +114,10 @@ def prepare_2412(
:param mat_table: R1 F4, Material property table number
:param color: R1 F5, Color, optional
:param num_nodes: R1 F6, Number of nodes on element
:param nodes_nums: R2 F1, Node labels defining element
:param nodes_nums: R2 F1 (R3 FOR RODS), Node labels defining element
:param beam_orientation: R2 F1 FOR RODS ONLY, beam orientation node number
:param beam_foreend_cross: R2 F2 FOR RODS ONLY, beam fore-end cross section number
:param beam_aftend_cross: R2 F3 FOR RODS ONLY, beam aft-end cross section number
:param return_full_dict: If True full dict with all keys is returned, else only specified arguments are included
**Test prepare_2412**
Expand Down Expand Up @@ -113,6 +152,13 @@ def prepare_2412(
raise TypeError('num_nodes must be integer')
if np.array(nodes_nums).dtype != int and nodes_nums != None:
raise TypeError('nodes_nums must be integer')
if np.array(beam_orientation).dtype != int and beam_orientation != None:
raise TypeError('beam_orientation must be integer')
if np.array(beam_foreend_cross).dtype != int and beam_foreend_cross != None:
raise TypeError('beam_foreend_cross must be integer')
if np.array(beam_aftend_cross).dtype != int and beam_aftend_cross != None:
raise TypeError('beam_aftend_cross must be integer')


dataset={
'type': 2412,
Expand All @@ -122,6 +168,9 @@ def prepare_2412(
'mat_table': mat_table,
'color': color,
'num_nodes': num_nodes,
'beam_orientation': beam_orientation,
'beam_foreend_cross': beam_foreend_cross,
'beam_aftend_cross': beam_aftend_cross,
'nodes_nums': nodes_nums
}

Expand Down
36 changes: 30 additions & 6 deletions tests/test_2412.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,34 @@
import pyuff

def test_read_2412():
# -- Load small test file
uff_ascii = pyuff.UFF('./data/mesh_Oros-modal_uff15_uff2412.uff')
a = uff_ascii.read_sets(2)

# -- Test legacy interface
np.testing.assert_array_equal(a['quad']['nodes_nums'][0], np.array([1, 25, 48, 24]))
np.testing.assert_array_equal(a['quad']['nodes_nums'][-1], np.array([50, 74, 73, 49]))
# -- Test new interface
np.testing.assert_array_equal(a[44][0]['nodes_nums'], np.array([1, 25, 48, 24]))
np.testing.assert_array_equal(a[44][-1]['nodes_nums'], np.array([50, 74, 73, 49]))

# -- Load bigger test file with rods
uff_ascii = pyuff.UFF('./data/simcenter_exported_result.uff')
a = uff_ascii.read_sets(2)

# -- Test new interface
assert all(['type' in a, 21 in a, 91 in a, 94 in a, len(a) == 4])
np.testing.assert_array_equal(a[21][0]['nodes_nums'], np.array([1894, 1443]))
np.testing.assert_array_equal(a[94][0]['nodes_nums'], np.array([1870, 1046, 1, 946]))
assert sorted(list(a[21][0].keys())) == ['beam_aftend_cross', 'beam_foreend_cross', 'beam_orientation', 'color', 'element_nums', 'fe_descriptor', 'mat_table', 'nodes_nums', 'num_nodes', 'phys_table']



def test_read_write_2412_mixed():
# Read dataset 2412 in test file
uff_ascii = pyuff.UFF('./data/mesh_test_uff2412_mixed.uff')
a = uff_ascii.read_sets(2)

# Test
np.testing.assert_array_equal(a['triangle']['nodes_nums'][-1], np.array([3, 6, 11]))
np.testing.assert_array_equal(a['quad']['nodes_nums'][-1], np.array([3, 4, 5, 6]))
Expand All @@ -26,22 +45,26 @@ def test_read_write_2412_mixed():
# Read dataset 2412 in written file
uff_ascii = pyuff.UFF('./data/tmp.uff')
b = uff_ascii.read_sets(0)

# Test
np.testing.assert_array_equal(a['triangle']['nodes_nums'], b['triangle']['nodes_nums'])
np.testing.assert_array_equal(a['quad']['nodes_nums'], b['quad']['nodes_nums'])
np.testing.assert_array_equal(a[41], b[41])
np.testing.assert_array_equal(a[44], b[44])

def test_prepare_2412():
dict_2412 = pyuff.prepare_2412(return_full_dict=True)

x = sorted(list(dict_2412.keys()))
y = sorted(['type',
y = sorted(['beam_aftend_cross',
'beam_foreend_cross',
'beam_orientation',
'color',
'element_nums',
'fe_descriptor',
'phys_table',
'mat_table',
'color',
'nodes_nums',
'num_nodes',
'nodes_nums'])
'phys_table',
'type'])
np.testing.assert_array_equal(x,y)

#empty dictionary test
Expand All @@ -51,6 +74,7 @@ def test_prepare_2412():
if x2['type'] != 2412:
raise Exception('Not correct type')


if __name__ == '__main__':
# test_read_2412()
test_read_write_2412_mixed()

0 comments on commit b600e0f

Please sign in to comment.