Fiber Section Properties Do Not Update Properly After Rotation
Introduction
When working with fiber sections in structural analysis, accurate section properties are crucial for correct stiffness and strength calculations. However, a critical issue has been identified in the opstool
library, where the section properties do not update correctly after rotation. This article will delve into the problem, provide a step-by-step guide to reproduce the issue, and discuss the expected and actual behavior.
Description
The issue arises when using the rotate
function on a FiberSecMesh
section in opstool
. Specifically, the moment of inertia (Iy
, Iz
), product of inertia (Iyz
), and the principal axis angle (phi
) remain unchanged after rotation, which is incorrect.
Steps to Reproduce
To reproduce the issue, follow these steps:
- Create a rectangular fiber section: Use
FiberSecMesh
to create a rectangular section. - Retrieve and store its initial section properties: Get the section properties for the unrotated section.
- Rotate the section by 30 degrees: Rotate the section by 30 degrees and retrieve the new section properties.
- Rotate another instance of the section by 90 degrees: Create a new section and rotate it by 90 degrees, then retrieve the new section properties.
- Compare the section properties before and after rotation: Compare the section properties before and after rotation to identify the issue.
Code Example
Here is a code example that demonstrates the issue:
import opstool as opst
import openseespy.opensees as ops
import matplotlib.pyplot as plt
# Create a new model
ops.wipe()
ops.model("basic", "-ndm", 3, "-ndf", 6)
# Define a material for the section
ops.uniaxialMaterial("Elastic", 1, 29000.0)
# Create a rectangular section using FiberSecMesh
outlines = [[0, 0], [4, 0], [4, 2], [0, 2]] # 4×2 rectangle
SEC = opst.pre.section.FiberSecMesh(sec_name="rectangular section")
patch = opst.pre.section.create_polygon_patch(outlines)
SEC.add_patch_group({"patch1": patch})
SEC.set_mesh_size({"patch1": 0.2}) # Set mesh size
SEC.set_ops_mat_tag({"patch1": 1}) # Assign material
SEC.mesh()
# Get section properties for unrotated section
props_original = SEC.get_frame_props(display_results=True)
# Rotate the section by 30 degrees
SEC.rotate(30)
# Get section properties for rotated section
props_rotated = SEC.get_frame_props(display_results=True)
# Create a new section for 90-degree rotation
SEC2 = opst.pre.section.FiberSecMesh(sec_name="rectangular section 90 deg")
patch = opst.pre.section.create_polygon_patch(outlines)
SEC2.add_patch_group({"patch1": patch})
SEC2.set_mesh_size({"patch1": 0.2})
SEC2.set_ops_mat_tag({"patch1": 1})
SEC2.mesh()
# Rotate by 90 degrees
SEC2.rotate(90)
# Get section properties for 90-degree rotated section
props_90 = SEC2.get_frame_props(display_results=True)
# Compare key properties
comparison = {
"Property": ["Area", "Iy", "Iz", "Iyz", "Principal axis angle"],
"Original": [props_original["A"], props_original["Iy"], props_original["Iz"],
props_original["Iyz"], props_original["phi"]],
"Rotated 30°": [props_rotated["A"], props_rotated["Iy"], props_rotated["Iz"],
props_rotated["Iyz"], props_rotated["phi"]],
"Rotated 90°": [props_90["A"], props_90["Iy"], props_90["Iz"],
props_90["Iyz"], props_90["phi"]]
}
print("\nComparison of Section Properties:")
print(f"{'Property':<20} {'Original':<15} {'Rotated 30°':<15} {'Rotated 90°':<15}")
print("-" * 65)
for i in range(len(comparison["Property"])):
print(f"{comparison['Property'][i]:<20} {comparison['Original'][i]:<15.6f} "
f"{comparison['Rotated 30°'][i]:<15.6f} {comparison['Rotated 90°'][i]:<15.6f}")
Expected Behavior
The expected behavior is that the section properties (Iy
, Iz
, Iyz
, and phi
) should change appropriately after rotation. Specifically:
- The moment of inertia (
Iy
,Iz
) should change to reflect the new orientation of the section. - The product of inertia (
Iyz
) should change to reflect the new orientation of the section. - The principal axis angle (
phi
) should reflect the applied rotation (e.g., rotating a rectangular section should swapIy
andIz
for a 90-degree rotation).
Actual Behavior
The actual behavior is that the moment of inertia (Iy
, Iz
), product of inertia (Iyz
), and principal axis angle (phi
) remain unchanged after rotation.
Output
Here is the output of the code example:
Comparison of Section Properties:
Property Original Rotated 30° Rotated 90°
-------------------------------------------------------------
Area 8.000000 8.000000 8.000000
Iy 2.666667 2.666667 2.666667
Iz 10.666667 10.666667 10.666667
Iyz 0.000000 0.000000 0.000000
Principal axis angle -90.000000 -90.000000 -90.000000
Environment
The issue was reproduced on the following environment:
- Operating System: Windows 10
- Python Version: 3.10.10
- opstool Version: 1.0.9
- OpenSeesPy Version: 3.5.1.12
Q: What is the issue with fiber section properties not updating properly after rotation?
A: The issue arises when using the rotate
function on a FiberSecMesh
section in opstool
. Specifically, the moment of inertia (Iy
, Iz
), product of inertia (Iyz
), and the principal axis angle (phi
) remain unchanged after rotation, which is incorrect.
Q: Why is this issue critical for structural analysis?
A: This issue is particularly critical for structural analysis where accurate section properties are required for correct stiffness and strength calculations. Inaccurate section properties can lead to incorrect results, which can have serious consequences in real-world applications.
Q: What are the expected and actual behaviors of the section properties after rotation?
A: The expected behavior is that the section properties (Iy
, Iz
, Iyz
, and phi
) should change appropriately after rotation. Specifically:
- The moment of inertia (
Iy
,Iz
) should change to reflect the new orientation of the section. - The product of inertia (
Iyz
) should change to reflect the new orientation of the section. - The principal axis angle (
phi
) should reflect the applied rotation (e.g., rotating a rectangular section should swapIy
andIz
for a 90-degree rotation).
The actual behavior is that the moment of inertia (Iy
, Iz
), product of inertia (Iyz
), and principal axis angle (phi
) remain unchanged after rotation.
Q: How can I reproduce the issue?
A: To reproduce the issue, follow these steps:
- Create a rectangular fiber section: Use
FiberSecMesh
to create a rectangular section. - Retrieve and store its initial section properties: Get the section properties for the unrotated section.
- Rotate the section by 30 degrees: Rotate the section by 30 degrees and retrieve the new section properties.
- Rotate another instance of the section by 90 degrees: Create a new section and rotate it by 90 degrees, then retrieve the new section properties.
- Compare the section properties before and after rotation: Compare the section properties before and after rotation to identify the issue.
Q: What is the code example that demonstrates the issue?
A: Here is a code example that demonstrates the issue:
import opstool as opst
import openseespy.opensees as ops
import matplotlib.pyplot as plt
# Create a new model
ops.wipe()
ops.model("basic", "-ndm", 3, "-ndf", 6)
# Define a material for the section
ops.uniaxialMaterial("Elastic", 1, 29000.0)
# Create a rectangular section using FiberSecMesh
outlines = [[0, 0], [4, 0], [4, 2], [0, 2]] # 4×2 rectangle
SEC = opst.pre.section.FiberSecMesh(sec_name="rectangular section")
patch = opst.pre.section.create_polygon_patch(outlines)
SEC.add_patch_group({"patch1": patch})
SEC.set_mesh_size({"patch1": 0.2}) # Set mesh size
SEC.set_ops_mat_tag({"patch1": 1}) # Assign material
SEC.mesh()
# Get section properties for unrotated section
props_original = SEC.get_frame_props(display_results=True)
# Rotate the section by 30 degrees
SEC.rotate(30)
# Get section properties for rotated section
props_rotated = SEC.get_frame_props(display_results=True)
# Create a new section for 90-degree rotation
SEC2 = opst.pre.section.FiberSecMesh(sec_name="rectangular section 90 deg")
patch = opst.pre.section.create_polygon_patch(outlines)
SEC2.add_patch_group({"patch1": patch})
SEC2.set_mesh_size({"patch1": 0.2})
SEC2.set_ops_mat_tag({"patch1": 1})
SEC2.mesh()
# Rotate by 90 degrees
SEC2.rotate(90)
# Get section properties for 90-degree rotated section
props_90 = SEC2.get_frame_props(display_results=True)
# Compare key properties
comparison = {
"Property": ["Area", "Iy", "Iz", "Iyz", "Principal axis angle"],
"Original": [props_original["A"], props_original["Iy"], props_original["Iz"],
props_original["Iyz"], props_original["phi"]],
"Rotated 30°": [props_rotated["A"], props_rotated["Iy"], props_rotated["Iz"],
props_rotated["Iyz"], props_rotated["phi"]],
"Rotated 90°": [props_90["A"], props_90["Iy"], props_90["Iz"],
props_90["Iyz"], props_90["phi"]]
}
print("\nComparison of Section Properties:")
print(f"{'Property':<20} {'Original':<15} {'Rotated 30°':<15} {'Rotated 90°':<15}")
print("-" * 65)
for i in range(len(comparison["Property"])):
print(f"{comparison['Property'][i]:<20} {comparison['Original'][i]:<15.6f} "
f"{comparison['Rotated 30°'][i]:<15.6f} {comparison['Rotated 90°'][i]:<15.6f}")
Q: What is the output of the code example?
A: Here is the output of the code example:
Comparison of Section Properties:
Property Original Rotated 30° Rotated 90°
-------------------------------------------------------------
Area 8.000000 8.000000 8.000000
Iy 2.666667 2.666667 2.666667
Iz 10.666667 10.666667 10.666667
Iyz 0.000000 0.000000 0.000000
Principal axis angle -90.000000 -90.000000 -90.000000
Q: What is the environment in which the issue was reproduced?
A: The issue was reproduced on the following environment:
- Operating System: Windows 10
- Python Version: 3.10.10
- opstool Version: 1.0.9
- OpenSeesPy Version: 3.5.1.12