OpenSTRAN package
Submodules
OpenSTRAN.Coordinates module
- class OpenSTRAN.Coordinates.Coordinate(x: float, y: float, z: float)[source]
Bases:
objectA class representing a 3D coordinate in space.
- Variables:
x – The x-coordinate in feet
y – The y-coordinate in feet
z – The z-coordinate in feet
coordinates – A tuple containing the (x, y, z) coordinates
vector – A numpy array representation of the coordinate vector
- coordinates: tuple[float, float, float]
- classmethod from_tuple(coordinates: tuple[float, float, float]) Self[source]
Create a Coordinate instance from a tuple of x, y, z values.
- Parameters:
coordinates (tuple[float, float, float]) – A tuple containing (x, y, z) coordinate values
- Returns:
A new Coordinate instance
- Return type:
Self
- properties() dict[str, Any][source]
Return the dataclass properties as a dictionary.
- Returns:
Dictionary of this instance’s fields
- Return type:
dict[str, Any]
- vector: ndarray
- x: float
- y: float
- z: float
OpenSTRAN.Member module
- class OpenSTRAN.Member.Member(nodes: ~OpenSTRAN.Nodes.Nodes, node_i: ~OpenSTRAN.Node.Node, node_j: ~OpenSTRAN.Node.Node, i_release: bool, j_release: bool, E: float, Ixx: float, Iyy: float, A: float, G: float, J: float, mesh: int, bracing: str | list[float], shape: str, count: int = 0, submembers: dict[int, ~OpenSTRAN.Submember.SubMember] = <factory>)[source]
Bases:
objectRepresents a 3D space frame member connecting two nodes.
A member is a structural element that connects two nodes and can be discretized into submembers for analysis. It supports various boundary conditions, material properties, and loading conditions.
- Variables:
nodes (Nodes) – Reference to the Nodes collection object.
node_i (Node) – Start node of the member.
node_j (Node) – End node of the member.
i_release (bool) – Boundary condition at node i (False = fixed, True = pinned).
j_release (bool) – Boundary condition at node j (False = fixed, True = pinned).
E (float) – Young’s modulus in ksi.
Ixx (float) – Strong axis moment of inertia in in^4.
Iyy (float) – Weak axis moment of inertia in in^4.
A (float) – Cross-sectional area in in^2.
G (float) – Shear modulus in ksi.
J (float) – Polar moment of inertia in in^4.
mesh (int) – Number of discretizations (submembers) along the member span.
bracing (str | list[float]) – Lateral bracing configuration. Can be ‘continuous’, ‘quarter’, ‘third’, ‘midspan’, or a list of bracing locations along the span.
shape (str) – Cross-sectional shape identifier.
length (float) – Calculated length of the member (in).
Cb (float) – Lateral-torsional buckling coefficient.
count (int) – Counter for submember creation.
submembers (dict[int, SubMember]) – Dictionary of submembers indexed by creation order.
- A: float
- Cb: float
- E: float
- G: float
- Ixx: float
- Iyy: float
- J: float
- add_distributed_load(Mag1: float, Mag2: float, direction: str, loc1: float, loc2: float)[source]
Apply a trapezoidal distributed load along the member.
Applies a distributed load with linearly varying magnitude over a specified portion of the member span. Handles loading that spans across multiple submembers by calculating equivalent nodal actions for each affected segment.
- Parameters:
Mag1 (float) – Starting magnitude of the distributed load in kips.
Mag2 (float) – Ending magnitude of the distributed load in kips.
direction (str) – Load direction - global (‘X’, ‘Y’, ‘Z’) or local (‘x’, ‘y’, ‘z’).
loc1 (float) – Starting location of load along member span as percentage (0-100%).
loc2 (float) – Ending location of load along member span as percentage (0-100%).
- Returns:
None
- Return type:
None
- Raises:
ValueError – If direction is not one of ‘X’, ‘Y’, ‘Z’, ‘x’, ‘y’, ‘z’.
- add_mesh(nodes: Nodes, node_i: Node, node_j: Node, mesh: int, l: float) list[Node][source]
Create intermediate mesh nodes along the member span.
Generates evenly spaced nodes along the member length based on the mesh parameter. These nodes are used as intermediary connection points for submembers in the discretization process.
- Parameters:
- Returns:
List of intermediate mesh nodes along the member
- Return type:
list[Node]
- add_point_load(mag: float, direction: str, location: float) None[source]
Apply a concentrated point load to the member.
Applies a point load at a specified location along the member span. The load can be specified in either global (X, Y, Z) or local (x, y, z) coordinates. The method calculates equivalent nodal actions and distributes loads to the appropriate nodes and submembers.
- Parameters:
mag (float) – Magnitude of the load in kips.
direction (str) – Load direction - global (‘X’, ‘Y’, ‘Z’) or local (‘x’, ‘y’, ‘z’).
location (float) – Load location as percentage of member span (0-100%).
- Returns:
None
- Return type:
None
- Raises:
ValueError – If direction is not one of ‘X’, ‘Y’, ‘Z’, ‘x’, ‘y’, ‘z’.
- add_submember(node_i: Node, node_j: Node, i_release: bool, j_release: bool, E: float, Ixx: float, Iyy: float, A: float, G: float, J: float) None[source]
Add a submember to the member collection.
Creates a new submember element connecting two nodes with specified boundary conditions and material properties. The submember is stored in the submembers dictionary using an auto-incremented counter.
- Parameters:
node_i (Node) – Start node of the submember
node_j (Node) – End node of the submember
i_release (bool) – Release condition at start node (False = fixed, True = pinned)
j_release (bool) – Release condition at end node (False = fixed, True = pinned)
E (float) – Young’s modulus in ksi
Ixx (float) – Strong axis moment of inertia in in^4
Iyy (float) – Weak axis moment of inertia in in^4
A (float) – Cross-sectional area in in^2
G (float) – Shear modulus in ksi
J (float) – Polar moment of inertia in in^4
- Returns:
None
- Return type:
None
- bracing: str | list[float]
- calculate_Cb() float[source]
Calculate the lateral-torsional buckling coefficient (Cb) for the member.
Computes Cb based on moment variation along unbraced spans using the standard AISC formula: Cb = 12.5*Mmax / (2.5*Mmax + 3*Ma + 4*Mb + 3*Mc). The calculation accounts for lateral bracing locations and interpolates moments at quarter-span points. The result is limited to a maximum of 3.0.
- Returns:
The lateral-torsional buckling coefficient, limited to 3.0 maximum.
- Return type:
float
- calculate_length(node_i: Node, node_j: Node) float[source]
Calculate the length of the member using the Euclidean distance formula.
Computes the 3D distance between two nodes based on their coordinate positions in the global reference frame.
- count: int
- i_release: bool
- j_release: bool
- length: float
- mesh: int
- properties() dict[str, Any][source]
Return all member properties as a dictionary.
Converts the dataclass instance into a dictionary representation containing all field names and their current values.
- Returns:
Dictionary containing all member attributes and their values
- Return type:
dict[str, Any]
- second_order() None[source]
Apply second-order (P-delta) effects to account for geometric nonlinearity.
Constructs and adds geometric stiffness matrices to all submembers to account for second-order effects including P-delta moments. This modifies the local stiffness matrix of each submember by including the effects of axial forces on bending behavior.
- Returns:
None
- Return type:
None
- shape: str
OpenSTRAN.Members module
- class OpenSTRAN.Members.Members(nodes: Nodes, count: int = 0, members: dict[int, ~OpenSTRAN.Member.Member]=<factory>)[source]
Bases:
objectContainer class for managing member (element) objects.
- Variables:
nodes – Reference to the global Nodes collection
count – Number of members added to the collection
members – Mapping of member ID to Member object
- addMember(node_i: Node, node_j: Node, i_release: bool = False, j_release: bool = False, E: float = 29000.0, Ixx: float = 88.6, Iyy: float = 2.36, A: float = 4.16, G: float = 12000.0, J: float = 0.0704, mesh: int = 50, bracing: str = 'continuous', shape: str = 'W12x14') Member[source]
Add a member to the model.
- Parameters:
node_i (Node) – Start node of the member
node_j (Node) – End node of the member
i_release (bool) – True if start node is released (pinned). Defaults to False.
j_release (bool) – True if end node is released (pinned). Defaults to False.
E (float) – Young’s modulus in ksi. Defaults to 29000.0.
Ixx (float) – Moment of inertia about the strong axis in in^4. Defaults to 88.6.
Iyy (float) – Moment of inertia about the weak axis in in^4. Defaults to 2.36.
A (float) – Cross-sectional area in in^2. Defaults to 4.16.
G (float) – Shear modulus in ksi. Defaults to 12000.0.
J (float) – Polar moment of inertia in in^4. Defaults to 0.0704.
mesh (int) – Number of discretizations per member. Defaults to 50.
bracing (str) – Bracing type (e.g., “continuous”). Defaults to “continuous”.
shape (str) – Section shape name (e.g., “W12x14”). Defaults to “W12x14”.
- Returns:
The created Member instance
- Return type:
- Example:
>>> M1 = frame.members.addMember(N1, N2) >>> M2 = frame.members.addMember(N2, N3)
- count: int
OpenSTRAN.Node module
- class OpenSTRAN.Node.Node(coordinates: Coordinate, node_ID: int, mesh_node: bool = False, Fx: float = 0.0, Fy: float = 0.0, Fz: float = 0.0, Mx: float = 0.0, My: float = 0.0, Mz: float = 0.0, Ux: float = 0.0, Uy: float = 0.0, Uz: float = 0.0, phi_x: float = 0.0, phi_y: float = 0.0, phi_z: float = 0.0, eFx: float = 0.0, eFy: float = 0.0, eFz: float = 0.0, eMx: float = 0.0, eMy: float = 0.0, eMz: float = 0.0, Rx: float = 0.0, Ry: float = 0.0, Rz: float = 0.0, Rmx: float = 0.0, Rmy: float = 0.0, Rmz: float = 0.0, plane: str | None = None, restraint: list[int] = <factory>)[source]
Bases:
objectA class representing a node in the structural analysis model.
- Variables:
coordinates – The coordinate object defining the node’s position
node_ID – Unique identifier for the node
mesh_node – Indicates if this is a mesh node. Defaults to False
Fx – Applied force in the x-direction in kips. Defaults to 0.0
Fy – Applied force in the y-direction in kips. Defaults to 0.0
Fz – Applied force in the z-direction in kips. Defaults to 0.0
Mx – Applied moment about the x-axis in kip-ft. Defaults to 0.0
My – Applied moment about the y-axis in kip-ft. Defaults to 0.0
Mz – Applied moment about the z-axis in kip-ft. Defaults to 0.0
restraint – List of 6 integers indicating restrained degrees of freedom [Ux, Uy, Uz, φx, φy, φz]. Defaults to [0, 0, 0, 0, 0, 0]
plane – The plane associated with the node. Defaults to None
- Fx: float
- Fy: float
- Fz: float
- Mx: float
- My: float
- Mz: float
- Rmx: float
- Rmy: float
- Rmz: float
- Rx: float
- Ry: float
- Rz: float
- Ux: float
- Uy: float
- Uz: float
- add_load(mag: float, lType: str = 'moment', direction: str = 'y') None[source]
Add a load to the node.
- Parameters:
mag (float) – Magnitude of the load. Units are kips for forces and kip-ft for moments.
lType (str) – Type of load. Either ‘moment’ or ‘force’. Defaults to ‘moment’.
direction (str) – Direction of the load. ‘X’, ‘Y’, or ‘Z’. Defaults to ‘y’.
- Note:
For moments, the magnitude is multiplied by 12 (kip-in to kip-ft conversion)
- add_restraint(restraint: list[int]) None[source]
Add restraint to the nodal degrees of freedom.
- Parameters:
restraint (list[int]) –
List of 6 integers (0 or 1) indicating which degrees of freedom are restrained. Format: [Ux, Uy, Uz, φx, φy, φz], where 1 means restrained and 0 means free. Examples:
Pinned node: [1, 1, 1, 0, 0, 0]
Fixed node: [1, 1, 1, 1, 1, 1]
Roller in x-direction: [0, 1, 1, 0, 0, 0]
- Raises:
ValueError – If restraint is not a list of exactly 6 integers, each being 0 or 1
- coordinates: Coordinate
- eFx: float
- eFy: float
- eFz: float
- eMx: float
- eMy: float
- eMz: float
- mesh_node: bool
- node_ID: int
- phi_x: float
- phi_y: float
- phi_z: float
- plane: str | None
- properties() dict[str, Any][source]
Return the dataclass properties as a dictionary.
- Returns:
Dictionary of this instance’s fields
- Return type:
dict[str, Any]
- restraint: list[int]
OpenSTRAN.Nodes module
- class OpenSTRAN.Nodes.Nodes(plane: str | None = None, count: int = 0, nodes: dict[int, ~OpenSTRAN.Node.Node]=<factory>, x: list[float] = <factory>, y: list[float] = <factory>, z: list[float] = <factory>)[source]
Bases:
objectA container class for managing user-defined node objects in the structural model.
- Variables:
plane – The plane constraint associated with the nodes
count – The total number of nodes added
nodes – Dictionary mapping node IDs to Node objects
x – List of x-coordinates
y – List of y-coordinates
z – List of z-coordinates
- add_node(x: float, y: float, z: float, mesh_node: bool = False) Node[source]
Add a node to the model at the specified coordinates.
- Parameters:
x (float) – x-coordinate in feet
y (float) – y-coordinate in feet
z (float) – z-coordinate in feet
mesh_node (bool) – Whether this is a mesh node. Defaults to False.
- Returns:
The added or existing node object
- Return type:
- Example:
>>> N1 = frame.nodes.add_node(0, 0, 0) >>> N2 = frame.nodes.add_node(0, 10, 0) >>> N3 = frame.nodes.add_node(10, 10, 0) >>> N4 = frame.nodes.add_node(10, 0, 0)
- count: int
- find_node(x: float, y: float, z: float) Node | None[source]
Find a node in the model at the specified coordinates.
- Parameters:
x (float) – x-coordinate in feet
y (float) – y-coordinate in feet
z (float) – z-coordinate in feet
- Returns:
The matching node object if found, None otherwise
- Return type:
Node | None
- plane: str | None
- properties() dict[str, Any][source]
Return the dataclass properties as a dictionary.
- Returns:
Dictionary of this instance’s fields
- Return type:
dict[str, Any]
- x: list[float]
- y: list[float]
- z: list[float]
OpenSTRAN.Solver module
- class OpenSTRAN.Solver.Solver[source]
Bases:
objectSolver class for structural finite element analysis.
This class performs finite element analysis on structural models by assembling the global stiffness matrix, applying boundary conditions, and solving for nodal displacements and member forces.
- Variables:
nDoF – Total number of degrees of freedom in the structure
pinDoF – List of pinned (rotational) degrees of freedom indices
restrainedDoF – List of restrained degrees of freedom indices
Kp – Primary stiffness matrix for the structure
force_vector – Global force vector with applied loads
global_displacement_vector – Global displacement vector at all nodes
global_force_vector – Global reaction force vector
- AddMemberToKp(node_ID_i: int, node_ID_j: int, i_release: bool, j_release: bool, KG: ndarray) None[source]
Add member stiffness contributions to the global stiffness matrix.
Extracts the appropriate submatrix from the member’s global stiffness matrix based on end releases and assembles it into the primary stiffness matrix at the correct locations corresponding to the member’s nodes.
- Parameters:
node_ID_i (int) – Node ID at the start of the member
node_ID_j (int) – Node ID at the end of the member
i_release (bool) – Whether the i-node has rotational releases (pinned)
j_release (bool) – Whether the j-node has rotational releases (pinned)
KG (numpy.ndarray) – Global stiffness matrix of the member (12x12 or reduced)
- Returns:
None
- Return type:
None
- solve(nodes: Nodes, members: Members) None[source]
Solve the structural system for displacements and member forces.
This method performs a complete finite element analysis including:
Assembly of the global stiffness matrix
Application of boundary conditions
Solution for nodal displacements using matrix reduction
Computation of member forces and reactions
Removal of equivalent nodal actions (distributed loads)
OpenSTRAN.Submember module
- class OpenSTRAN.Submember.SubMember(node_i: Node, node_j: Node, i_release: bool, j_release: bool, E: float, Ixx: float, Iyy: float, A: float, G: float, J: float, ENAs: dict[str, list[float]]=<factory>, results: dict[str, list[float]]=<factory>)[source]
Bases:
objectA 3D space-frame submember between mesh nodes.
A discretized sub-element between two mesh nodes containing geometry, section properties, and methods to build local and geometric stiffness matrices.
- Variables:
node_i – Start node of the submember
node_j – End node of the submember
i_release – Release (pinned) flag at the start node
j_release – Release (pinned) flag at the end node
E – Young’s modulus
Ixx – Moment of inertia about the strong axis
Iyy – Moment of inertia about the weak axis
A – Cross-sectional area
G – Shear modulus
J – Polar moment of inertia
length – Submember length (computed)
rotation_matrix – Rotation matrix from local to global coordinates
transformation_matrix – Transformation matrix for coordinate conversion
Kl – Local stiffness matrix
Kg – Global stiffness matrix
- A: float
- E: float
- ENAs: dict[str, list[float]]
- G: float
- Ixx: float
- Iyy: float
- J: float
- Kg: ndarray
- Kl: ndarray
- build_geometric_stiffness_matrix() ndarray[source]
Compute the geometric (P-Delta) stiffness matrix from results.
Uses the axial and moment results stored in self.results to assemble the geometric stiffness matrix for second-order effects.
- Returns:
Geometric stiffness matrix in local element DOFs.
- Return type:
np.ndarray
- build_rotation_matrix(node_i: Node, node_j: Node, i_release: bool, j_release: bool) ndarray[source]
Build the rotation/transformation matrix for the submember.
Establishes the local x,y,z unit vectors using a Gram-Schmidt approach and constructs the transformation matrix between the local element frame and the global frame. The size of the returned matrix depends on release conditions.
- build_stiffness_matrix(E: float, Izz: float, Iyy: float, A: float, G: float, J: float, l: float) ndarray[source]
- calculate_length(node_i: Node, node_j: Node) float[source]
Compute Euclidean length between two nodes.
- i_release: bool
- j_release: bool
- length: float
- properties() dict[str, Any][source]
Return all submember properties as a dictionary.
Converts the dataclass instance into a dictionary representation containing all field names and their current values.
- Returns:
Dictionary containing all member attributes and their values
- Return type:
dict[str, Any]
- results: dict[str, list[float]]
- rotation_matrix: ndarray
- transformation_matrix: ndarray
OpenSTRAN.model module
- class OpenSTRAN.model.Model(plane: str | None = None)[source]
Bases:
object3D space frame structural model.
This class represents a three-dimensional space frame for finite element analysis. The model neglects deformations due to transverse shear stresses and torsional warping, operating under the assumption that such effects are negligible in typical civil engineering applications.
- Parameters:
plane (str | None) – Constrains the model to a two-dimensional plane. Valid values are ‘xy’, ‘yz’, or ‘xz’. If None, the model is fully three-dimensional.
- Variables:
nodes – Collection of nodes in the structure
members – Collection of members (elements) in the structure
solver – Solver instance for performing structural analysis
- Example:
>>> import OpenSTRAN >>> frame_2d = OpenSTRAN.Model(plane='xy') >>> frame_3d = OpenSTRAN.Model()
- localMaxima(forces: list[float]) list[bool][source]
Identify local maxima in a force distribution.
Determines which points in the force distribution represent local maxima by comparing adjacent values, accounting for numerical precision with near-equal comparisons.
- Parameters:
forces (list[float]) – List of force values along a member or structure
- Returns:
Boolean list indicating local maxima positions
- Return type:
list[bool]
- localMinima(forces: list[float]) list[bool][source]
Identify local minima in a force distribution.
Determines which points in the force distribution represent local minima by comparing adjacent values, accounting for numerical precision with near-equal comparisons.
- Parameters:
forces (list[float]) – List of force values along a member or structure
- Returns:
Boolean list indicating local minima positions
- Return type:
list[bool]
- maxMbrForces() None[source]
Calculate maximum member forces and identify local extrema.
Computes the maximum values for all member internal forces (axial, shear, torsion, and bending moments) and identifies their local maxima and minima distributions along members.
- Returns:
None
- Return type:
None
Sets the following instance attributes:
axial_max, axial_maxima, axial_minima: Axial force results
torque_max, torque_maxima, torque_minima: Torsional moment results
Vy_max, Vy_maxima, Vy_minima: Y-direction shear force results
Vz_max, Vz_maxima, Vz_minima: Z-direction shear force results
Mzz_max, Mzz_maxima, Mzz_minima: Major axis bending moment results
Myy_max, Myy_maxima, Myy_minima: Minor axis bending moment results
- maxReactions() None[source]
Calculate maximum reaction forces and moments at restrained nodes.
Computes the maximum absolute values of reaction forces and moments across all support nodes in the structure.
- Returns:
None
- Return type:
None
Sets the following instance attributes:
Rx_max: Maximum X-direction reaction force
Ry_max: Maximum Y-direction reaction force
Rz_max: Maximum Z-direction reaction force
Rmx_max: Maximum X-direction reaction moment
Rmy_max: Maximum Y-direction reaction moment
Rmz_max: Maximum Z-direction reaction moment
- reactions() None[source]
Print nodal reactions to console.
Displays all reaction forces (Rx, Ry, Rz) and reaction moments (Mx, My, Mz) at all restrained support nodes in a formatted table.
- Returns:
None
- Return type:
None
- solve() None[source]
Solve the structural system and compute reactions and member forces.
This method performs a complete finite element analysis including:
Assembly and solution of the global stiffness system
Calculation of nodal reactions at restrained DOFs
Determination of member forces and local extrema
- Returns:
None
- Return type:
None
Module contents
OpenSTRAN - Open-source Structural Analysis Package.
A Python package for 3D finite element analysis of space frames. This package provides tools for structural modeling and analysis.