Skip to content

Commit

Permalink
add failure criteria (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
akaszynski authored Feb 23, 2022
1 parent 01d42eb commit 6a6f056
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 20 deletions.
20 changes: 20 additions & 0 deletions ansys/mapdl/reader/_rst_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,3 +313,23 @@
63: 'TE31',
64: 'TTOP'
}

# from fcCom.inc
STR_LIM_REF = {
86: 'XTEN',
87: 'XCMP',
88: 'YTEN',
89: 'YCMP',
90: 'ZTEN',
91: 'ZCMP',
92: 'XY',
93: 'YZ',
94: 'XZ',
95: 'XYCP',
96: 'YZCP',
97: 'XZCP',
98: 'XZIT',
99: 'XZIC',
100: 'YZIT',
101: 'YZIC',
}
115 changes: 95 additions & 20 deletions ansys/mapdl/reader/rst.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,34 @@

from ansys.mapdl.reader import _binary_reader, _reader
from ansys.mapdl.reader.mesh import Mesh
from ansys.mapdl.reader._binary_reader import (cells_with_any_nodes,
cells_with_all_nodes,
AnsysFile,
populate_surface_element_result)
from ansys.mapdl.reader._rst_keys import (geometry_header_keys,
element_index_table_info,
solution_data_header_keys,
solution_header_keys_dp,
result_header_keys,
boundary_condition_index_table,
DOF_REF)
from ansys.mapdl.reader._binary_reader import (
cells_with_any_nodes,
cells_with_all_nodes,
AnsysFile,
populate_surface_element_result
)
from ansys.mapdl.reader._rst_keys import (
geometry_header_keys,
element_index_table_info,
solution_data_header_keys,
solution_header_keys_dp,
result_header_keys,
boundary_condition_index_table,
DOF_REF,
STR_LIM_REF,
)
from ansys.mapdl.reader._mp_keys import mp_keys
from ansys.mapdl.reader.common import (read_table, parse_header,
AnsysBinary, read_standard_header,
rotate_to_global, PRINCIPAL_STRESS_TYPES,
STRESS_TYPES, STRAIN_TYPES,
THERMAL_STRAIN_TYPES)
from ansys.mapdl.reader.common import (
read_table,
parse_header,
AnsysBinary,
read_standard_header,
rotate_to_global,
PRINCIPAL_STRESS_TYPES,
STRESS_TYPES,
STRAIN_TYPES,
THERMAL_STRAIN_TYPES
)
from ansys.mapdl.reader.misc import vtk_cell_info, break_apart_surface
from ansys.mapdl.reader.rst_avail import AvailableResults
from ansys.mapdl.reader import elements
Expand Down Expand Up @@ -353,7 +364,7 @@ def read_mat_data(ptr):
# size of record (from fdresu.inc)
n_mat_prop = self._geometry_header.get('nMatProp')
for i in range(self._geometry_header['nummat']):
# Material Record pointers for the Material Id at I th Position
# Material Record pointers for the Material Id at I th Position
# is stored from location.
# NOTE: somewhere between 182 and 194 this changed from:
# 3+(I-1)*(158+1)+2 to 3+(I-1)*(158+1)+1+158
Expand Down Expand Up @@ -385,6 +396,24 @@ def read_mat_data(ptr):
else:
for i in range(-5, 10):
material[key] = read_mat_data(ptr)
# print(read_mat_data(ptr))

# documentation for this is hard to follow, but it boils down to
# the fact that "The record includes MP pointers followed by TB
# pointers for a single Material ID"
# So, after 80, these are all TB pointers, and fcCom.inc describes
# maximum stresses:
# co XTEN,XCMP,YTEN,YCMP,ZTEN,ZCMP,XY,YZ,XZ,XYCP,YZCP,XZCP
# co XZIT,XZIC,YZIT,YZIC = Puck inclination parameters
# only implemented for v194 and newer
try:
ptr = mat_data_ptr[163]
if ptr:
arr = self.read_record(self._geometry_header['ptrMAT'] + ptr)
str_lim = {key: arr[index] for (index, key) in STR_LIM_REF.items()}
material['stress_failure_criteria'] = str_lim
except:
pass

# store by material number
self._materials[mat_data_ptr[0]] = material
Expand All @@ -395,12 +424,12 @@ def materials(self):
Returns
-------
materials : dict
dict
Dictionary of Materials. Keys are the material numbers,
and each material is a dictionary of the material
properrties of that material with only the valid entries filled.
NOTES
Notes
-----
Material properties:
Expand Down Expand Up @@ -450,6 +479,52 @@ def materials(self):
- MGYY : Magnetic coercive force, element y direction (Charge / (Length*Time))
- MGZZ : Magnetic coercive force, element z direction (Charge / (Length*Time))
Materials may contain the key ``"stress_failure_criteria"``, which
contains failure criteria information for temperature-dependent stress
limits. This includes the following keys:
- XTEN : Allowable tensile stress or strain in the x-direction. (Must
be positive.)
- XCMP : Allowable compressive stress or strain in the
x-direction. (Defaults to negative of XTEN.)
- YTEN : Allowable tensile stress or strain in the y-direction. (Must
be positive.)
- YCMP : Allowable compressive stress or strain in the
y-direction. (Defaults to negative of YTEN.)
- ZTEN : Allowable tensile stress or strain in the z-direction. (Must
be positive.)
- ZCMP : Allowable compressive stress or strain in the
z-direction. (Defaults to negative of ZTEN.)
- XY : Allowable XY stress or shear strain. (Must be positive.)
- YZ : Allowable YZ stress or shear strain. (Must be positive.)
- XZ : Allowable XZ stress or shear strain. (Must be positive.)
- XYCP : XY coupling coefficient (Used only if Lab1 = S). Defaults to -1.0. [1]
- YZCP : YZ coupling coefficient (Used only if Lab1 = S). Defaults to -1.0. [1]
- XZCP : XZ coupling coefficient (Used only if Lab1 = S). Defaults to -1.0. [1]
- XZIT : XZ tensile inclination parameter for Puck failure index (default =
0.0)
- XZIC : XZ compressive inclination parameter for Puck failure index
(default = 0.0)
- YZIT : YZ tensile inclination parameter for Puck failure index
(default = 0.0)
- YZIC : YZ compressive inclination parameter for Puck failure index
(default = 0.0)
Examples
--------
Return the material properties from the example result
Expand Down Expand Up @@ -2850,7 +2925,7 @@ def exit_callback(plotter, RenderWindowInteractor, event):
plotter.add_key_event("q", q_callback)
if os.name == 'nt':
# Adding closing window callback
plotter.iren.add_observer(vtk.vtkCommand.ExitEvent,
plotter.iren.add_observer(vtk.vtkCommand.ExitEvent,
lambda render, event: exit_callback(plotter, render, event))

first_loop = True
Expand Down
113 changes: 113 additions & 0 deletions tests/test_rst.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ def materials_281_rst():
return pymapdl_reader.read_binary(rst_file)


@pytest.fixture(scope='module')
def materials_stress_lim_rst():
rst_file = os.path.join(testfiles_path, 'materials', 'stress_lim.rst')
return pymapdl_reader.read_binary(rst_file)


def test_map_flag_section_data():
# basic 4 element SHELL181 result files
shell181_2020r2 = os.path.join(testfiles_path, 'shell181_2020R2.rst')
Expand Down Expand Up @@ -500,6 +506,113 @@ def test_materials(materials_281_rst):
assert pytest.approx(ans_mat[key]) == known_material[key]


def test_materials_str_lim(materials_stress_lim_rst):
# output from:
# from ansys.mapdl.core import launch_mapdl
# mapdl = launch_mapdl()
# mapdl.post1()
# mapdl.set(1, 1)
# print(mapdl.tblist(mat=1))
#
# validate material stress limits can be extracted
# FC LIMIT (FCLI) Table For Material 1
# Stress Strength Limits
#
# 1
# Temps 0.0000000e+00
# XTEN 5.0000000e-01
# XCMP -2.5000000e-01
# YTEN 5.0000000e-01
# YCMP -2.5000000e-01
# ZTEN 5.0000000e+00
# ZCMP -5.0000000e+00
# XY 5.0000000e-01
# YZ 3.0000000e+00
# XZ 3.0000000e+00
# XYCP 0.0000000e+00
# YZCP 0.0000000e+00
# XZCP 0.0000000e+00
# XZIT 0.0000000e+00
# XZIC 0.0000000e+00
# YZIT 0.0000000e+00
# YZIC 0.0000000e+00
# GI/GII 0.0000000e+00
# ETA_L 0.0000000e+00
# ETA_T 0.0000000e+00
# ALPHA_0 0.0000000e+00
#
# FC LIMIT (FCLI) Table For Material 2
# Stress Strength Limits
# 1
# Temps 0.0000000e+00
# XTEN 2.0000000e+00
# XCMP -2.0000000e+00
# YTEN 2.0000000e+00
# YCMP -2.0000000e+00
# ZTEN 3.0000000e+00
# ZCMP -4.0000000e+00
# XY 1.0000000e+00
# YZ 2.0000000e+00
# XZ 2.0000000e+00
# XYCP 0.0000000e+00
# YZCP 0.0000000e+00
# XZCP 0.0000000e+00
# XZIT 0.0000000e+00
# XZIC 0.0000000e+00
# YZIT 0.0000000e+00
# YZIC 0.0000000e+00
# GI/GII 0.0000000e+00
# ETA_L 0.0000000e+00
# ETA_T 0.0000000e+00
# ALPHA_0 0.0000000e+00

mat = {}
mat[1] = {
'XTEN': 5.0000000e-01,
'XCMP': -2.5000000e-01,
'YTEN': 5.0000000e-01,
'YCMP': -2.5000000e-01,
'ZTEN': 5.0000000e+00,
'ZCMP': -5.0000000e+00,
'XY': 5.0000000e-01,
'YZ': 3.0000000e+00,
'XZ': 3.0000000e+00,
'XYCP': 0.0000000e+00,
'YZCP': 0.0000000e+00,
'XZCP': 0.0000000e+00,
'XZIT': 0.0000000e+00,
'XZIC': 0.0000000e+00,
'YZIT': 0.0000000e+00,
'YZIC': 0.0000000e+00,
}

mat[2] = {
'XTEN': 2.0000000e+00,
'XCMP': -2.0000000e+00,
'YTEN': 2.0000000e+00,
'YCMP': -2.0000000e+00,
'ZTEN': 3.0000000e+00,
'ZCMP': -4.0000000e+00,
'XY': 1.0000000e+00,
'YZ': 2.0000000e+00,
'XZ': 2.0000000e+00,
'XYCP': 0.0000000e+00,
'YZCP': 0.0000000e+00,
'XZCP': 0.0000000e+00,
'XZIT': 0.0000000e+00,
'XZIC': 0.0000000e+00,
'YZIT': 0.0000000e+00,
'YZIC': 0.0000000e+00,
}

ans_mat = materials_stress_lim_rst.materials[1]['stress_failure_criteria']

for mat_type, known_stress_lim in mat.items():
ans_mat = materials_stress_lim_rst.materials[mat_type]['stress_failure_criteria']
for key, value in known_stress_lim.items():
assert pytest.approx(ans_mat[key]) == known_stress_lim[key]


def test_materials_v150():
"""Validate on older result files"""
rst = pymapdl_reader.read_binary(examples.rstfile)
Expand Down
Binary file added tests/testfiles/materials/stress_lim.rst
Binary file not shown.

0 comments on commit 6a6f056

Please sign in to comment.