Извлечь напряжение в узлах, указанных в наборе узлов [Abaqus python odb access] - PullRequest
0 голосов
/ 24 марта 2020

Учитывая odb-файл Abaqus, включающий в себя набор узлов (например, 'ALL_SECS').

NODAL-величины, такие как координаты ('COORD') или смещение ('U'), могут быть извлечены в узлах узел, установленный по следующей схеме:

  • выберите шаг, кадр и выход поля (например, 'COORD', 'U')
  • getSubset (region =) выхода поля
  • получить атрибуты результирующих значений

Каким образом INTEGRATION_POINT-количества могут быть извлечены / интерполированы в узлах набора узлов? Как можно запросить выход поля в NODAL-позиции, используя abaqus- python?

from odbAccess import *
import numpy as np


# Helper function
def values_to_array(values, dim=2, item='data'):
    length = len(values)
    array = np.zeros((length, dim), dtype='float64')
    for index in range(length):
        array[index, :] = getattr(values[index], item)
    return array


# Prepare and open
odb = openOdb(path='job.odb')   # Solution of 2D-plane-stress model
instances = odb.rootAssembly.instances
instance = instances['PART']
sett = instance.nodeSets['ALL_SECS']
step = odb.steps.keys()[-1]


# Get coordinates and number of nodes in node set
frame = odb.steps[step].frames[-1]
values_xy = frame.fieldOutputs['COORD'].getSubset(region=sett).values
xy = values_to_array(values=values_xy, dim=2, item='dataDouble')

nbr_xy = len(values_xy)
print('len(values_xy)')
print(len(values_xy))

# Get nodal-quantity and number of nodes in node set
uvw = np.zeros((nbr_xy, 2), dtype=float)

outp = odb.steps[step].frames[-1].fieldOutputs['U']
values_u = outp.getSubset(region=sett).values
uvw = values_to_array(values=values_u, dim=2, item='dataDouble')
print('len(values_u)')
print(len(values_u))

eps = np.zeros((nbr_xy, 4), dtype=float)

outp = odb.steps[step].frames[-1].fieldOutputs['E']
values_eps = outp.getSubset(position=ELEMENT_NODAL, region=sett).values
# values_eps = outp.getSubset(position=ELEMENT_NODAL).getSubset(region=sett).values
print('len(values_eps)')
print(len(values_eps))

values_eps_nodal = outp.getSubset(position=NODAL, region=sett).values
print('len(values_eps_nodal)')
print(len(values_eps_nodal))

Выход:

len(values_xy)
147
len(values_u)
147
len(values_eps)
408
len(values_eps_nodal)
0

1 Ответ

0 голосов
/ 25 марта 2020

Следующее решение - это обходной путь для получения полной деформации (Fieldoutput 'E') в узлах, указанных в наборе узлов 'ALL_SECS'. Поскольку порядок извлеченных узлов неизвестен, информация о местоположении, то есть координаты узлов, также извлекается. I-я деформация в eps - это деформация по i-й координате в xy. Эта функция, по-видимому, отсутствует в Abaqus API. Специфичные для узла c данные, такие как смещения, могут быть легко извлечены, см. uv. Основные этапы извлечения данных деформации в узлах и местах элементов:

  • Определение координат
  • Определение отображения nodeLabel -> index
  • Объединение значений в узлах, экстраполируется из разных элементов с помощью скользящего среднего. ( См. Ссылку для объяснений )

Примечание: 2D модель odb


from odbAccess import *

import numpy as np
import pickle
from operator import attrgetter


def values_to_array(values, dim=2, item='data', dtype=np.float64):
    '''Thanks to https://stackoverflow.com/a/46925902/8935243'''
    array = np.array(
                map(attrgetter(item), values),
                dtype=dtype,
                )
    return array


def values_to_index_mapping(values, item='nodeLabel', check=True):
    node_labels = values_to_array(values, dim=1, item=item, dtype=np.int64)

    if check:
        assert len(set(node_labels)) == len(node_labels)

    mapping = {}
    for index, label in enumerate(node_labels):
        mapping[label] = index
    return mapping


odb = openOdb(path='job.odb')
instances = odb.rootAssembly.instances
instance = instances['PART']
sett = instance.nodeSets['ALL_SECS']
step = odb.steps.keys()[-1]

# Coordinates
frame = odb.steps[step].frames[-1]
values = frame.fieldOutputs['COORD'].getSubset(region=sett).values
xy = values_to_array(values=values, dim=2, item='data')

# Dimensions
nbr_xy = len(values)

# Mapping: nodeLabel -> index
index_map = values_to_index_mapping(values=values, check=True)

# Displacements
uv = np.zeros((nbr_xy, 2), dtype=float)
outp = odb.steps[step].frames[-1].fieldOutputs['U']
values = outp.getSubset(region=sett).values
uv[:, :] = values_to_array(values=values, dim=2, item='data')

# Strains
eps = np.zeros((nbr_xy, 4), dtype=float)
tmp = np.zeros((nbr_xy, 1), dtype=float)

values_eps = odb.steps[step].frames[-1].fieldOutputs['E'].getSubset(
                        position=ELEMENT_NODAL,
                        region=sett,
                        ).values
    # Moving average, as ELEMENT_NODAL does no averaging
    # and returns multiple values for nodes in sett
    for ee in values_eps:
        index = index_map[ee.nodeLabel]
        tmp[index] += 1
        eps[index] = (eps[index] * (tmp[index] - 1) + ee.data) / tmp[index]

odb.close()

...