Skip to content

Commit

Permalink
Pull request #74: Odbserver/integration points
Browse files Browse the repository at this point in the history
Merge in FMO/pylife from odbserver/integration_points to develop

* commit '5dfa5a4e6fbacf2c1224bbded62e21cc9e99224f':
  Implement integration point and element face positions in odbclient
  • Loading branch information
johannes-mueller committed Nov 24, 2021
2 parents f6b2172 + 5dfa5a4 commit 3c0c284
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 22 deletions.
16 changes: 13 additions & 3 deletions tools/odbclient/src/odbclient/odbclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,22 @@ def frame_ids(self, step_name):
def variable_names(self, step_name, frame_id):
return _ascii(_decode, self._query('get_variable_names', (step_name, frame_id)))

def variable(self, variable_name, instance_name, step_name, frame_id, nset_name='', elset_name=''):
response = self._query('get_variable', (instance_name, step_name, frame_id, variable_name, nset_name, elset_name))
def variable(self, variable_name, instance_name, step_name, frame_id, nset_name='', elset_name='', position=None):
"""Read field data.
Parameters
----------
...
position : string
Position within element. Terminology as in Abaqus .inp file:
"INTEGRATION POINTS", "CENTROIDAL", "WHOLE ELEMENT", "NODES",
"FACES", "AVERAGED AT NODES"
"""
response = self._query('get_variable', (instance_name, step_name, frame_id, variable_name, nset_name, elset_name, position))
(labels, index_labels, index_data, values) = response

index_labels = _ascii(_decode, index_labels)
if len(index_labels) == 2:
if len(index_labels) > 1:
index = pd.DataFrame(index_data, columns=index_labels).set_index(index_labels).index
else:
index = pd.Int64Index(index_data[:, 0], name=index_labels[0])
Expand Down
4 changes: 2 additions & 2 deletions tools/odbserver/odbserver/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ def variable_names(self, args):
_send_response(self._odb.variable_names(step, int(frame)))

def variable(self, args):
instance_name, step, frame, var_name, nset, elset = args
instance_name, step, frame, var_name, nset, elset, elem_pos = args
instance_name = str(instance_name)
var_name = str(var_name)
nset = str(nset)
elset = str(elset)
try:
variable = self._odb.variable(instance_name, step, frame, var_name, nset, elset)
variable = self._odb.variable(instance_name, step, frame, var_name, nset, elset, elem_pos)
except Exception as e:
_send_response(e)
else:
Expand Down
74 changes: 57 additions & 17 deletions tools/odbserver/odbserver/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def variable_names(self, step_name, frame_num):

return frame.fieldOutputs.keys()

def variable(self, instance_name, step_name, frame_num, variable_name, node_set_name, element_set_name):
def variable(self, instance_name, step_name, frame_num, variable_name, node_set_name, element_set_name, position=None):

def block_length(block):
if block.nodeLabels is not None:
Expand All @@ -141,12 +141,25 @@ def block_length(block):

def index_block_data(block):
stack = []
if block.nodeLabels is not None:
index_labels = []

if getattr(block, 'nodeLabels', None) is not None:
stack.append(block.nodeLabels)
if block.elementLabels is not None:
index_labels.append('node_id')

if getattr(block, 'elementLabels', None) is not None:
stack.append(block.elementLabels)
index_labels.append('element_id')

return np.vstack(stack)
if getattr(block, 'integrationPoints', None) is not None:
stack.append(block.integrationPoints)
index_labels.append('ipoint_id')

if getattr(block, 'faces', None) is not None:
stack.append(block.faces)
index_labels.append('face_id')

return np.vstack(stack), index_labels

try:
step = self._odb.steps[step_name]
Expand Down Expand Up @@ -184,12 +197,10 @@ def index_block_data(block):
raise KeyError(element_set_name)
region = element_set

pos = field.locations[0].position
if pos == ODB.INTEGRATION_POINT:
pos = ODB.ELEMENT_NODAL
position_str = position
position = _set_position(field, user_request=position_str)
field = field.getSubset(position=position)

if pos != "ABQDEFAULT":
field = field.getSubset(position=pos)
if region is not None:
field = field.getSubset(region=region)

Expand All @@ -204,7 +215,10 @@ def index_block_data(block):

values = np.empty((length, len(complabels)))

index_dim = 2 if pos == ODB.ELEMENT_NODAL else 1
if position in [ODB.INTEGRATION_POINT, ODB.ELEMENT_NODAL, ODB.ELEMENT_FACE]:
index_dim = 2
elif position in [ODB.CENTROID, ODB.WHOLE_ELEMENT, ODB.NODAL]:
index_dim = 1
index = np.empty((length, index_dim), dtype=np.int32)

i = 0
Expand All @@ -215,18 +229,12 @@ def index_block_data(block):
block_array = block.data
size = block_array.shape[0]

index_block = index_block_data(block)
index_block, index_labels = index_block_data(block)

index[i:i+size, :] = index_block.T
values[i:i+size, :] = block_array
i += size

if pos == ODB.NODAL:
index_labels = ['node_id']
elif pos == ODB.WHOLE_ELEMENT or pos == ODB.CENTROID:
index_labels = ['element_id']
else:
index_labels = ['node_id', 'element_id']
return (complabels, index_labels, index[:i, :], values[:i])

def _instance_or_rootasm(self, instance_name):
Expand All @@ -237,6 +245,38 @@ def _instance_or_rootasm(self, instance_name):
except Exception as e:
return e

def _set_position(field, user_request=None):
"""Translate string to symbolic constant and define default behavior.
Parameters
----------
field : Abaqus field object
Required if ``user_request=None``.
user_request : string
Abaqus .inp file terminology (*ELEMENT OUTPUT, position=...).
Returns
-------
position : symbolic constant
Abaqus Python interface terminology.
"""
_position_dict = {'INTEGRATION POINTS': ODB.INTEGRATION_POINT,
'CENTROIDAL': ODB.CENTROID,
'WHOLE ELEMENT': ODB.WHOLE_ELEMENT,
'NODES': ODB.ELEMENT_NODAL,
'FACES': ODB.ELEMENT_FACE,
'AVERAGED AT NODES': ODB.NODAL}

if user_request is not None:
return _position_dict[user_request]

else:
odb_pos = field.locations[0].position

if odb_pos == ODB.INTEGRATION_POINT:
return ODB.ELEMENT_NODAL

return odb_pos

def _get_frame(step, frame_id):
for frame in step.frames:
Expand Down

0 comments on commit 3c0c284

Please sign in to comment.