pycufsm.fsm =========== .. py:module:: pycufsm.fsm Functions --------- .. autoapisummary:: pycufsm.fsm.strip pycufsm.fsm.strip_new pycufsm.fsm.signature_ss pycufsm.fsm.m_recommend Module Contents --------------- .. py:function:: strip(props: numpy.ndarray, nodes: numpy.ndarray, elements: numpy.ndarray, lengths: numpy.ndarray, springs: numpy.ndarray, constraints: numpy.ndarray, GBT_con: pycufsm._types.GBT_Con, B_C: pycufsm._types.BC, m_all: numpy.ndarray, n_eigs: int, sect_props: pycufsm._types.Sect_Props) -> Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray] Perform a finite strip analysis Args: props (np.ndarray): Material properties | `[[mat_num, stiff_x, E_y, nu_x, nu_y, G_bulk], ...]` nodes (np.ndarray): Nodal properties | `[[node#, x, y, dof_x, dof_y, dof_z, dof_r, stress], ...]` elements (np.ndarray): Element properties | `[[elem#, node_i, node_j, thick, mat_num], ...]` lengths (np.ndarray): Half-wavelengths to analyse | `[length1, length2, ...]` These could be half-wavelengths for signature curve or physical lengths for general b.c. springs (np.ndarray): Nodal springs (if any) | `[[node#, node_pair, k_x, k_y, k_z, k_q, k_type, discrete, y_s], ...]` where `k_flag` is 0 for a foundation spring, or 1 for a total spring. discrete is 1 for a discrete spring. k_* are the spring stiffnesses for each DOF, and y_s is the location of the discrete spring; it is ignored if the spring is not discrete. constraints (np.ndarray): | `[[node#_e dof_e coeff node#_k dof_k], ...] where k=kept dof, e=dof to be eliminated. Each DOF is set as an integer where 1=x, 2=y, 3=z, 4=q. The resulting constraint will be `node_e_dof = coeff * node_k_dof` GBT_con (GBT_Con): GBT Configuration | { | "glob": [0|1, 0|1, ...], | "dist": [0|1, 0|1, ...], | "local": [0|1, 0|1, ...], | "other": [0|1, 0|1, ...], | "o_space": 1|2|3|4, | "norm": 0|1|2|3, | "couple": 1|2, | "orth": 1|2|3, | } GBT_con.glob,GBT_con.dist, GBT_con.local, GBT_con.other: vectors of 1's and 0's referring to the inclusion (1) or exclusion of a given mode from the analysis, GBT_con.o_space - choices of ST/O mode | 1: ST basis | 2: O space (null space of GDL) with respect to K_global | 3: O space (null space of GDL) with respect to Kg_global | 4: O space (null space of GDL) in vector sense GBT_con.norm - code for normalization (if normalization is done at all) | 0: no normalization, | 1: vector norm | 2: strain energy norm | 3: work norm GBT_con.couple - coupled basis vs uncoupled basis for general B.C. especially for non-simply supported B.C. | 1: uncoupled basis, the basis will be block diagonal | 2: coupled basis, the basis is fully spanned GBT_con.orth - natural basis vs modal basis | 1: natural basis | 2: modal basis, axial orthogonality | 3: modal basis, load dependent orthogonality B_C (str): Boundary condition to be analyzed | 'S-S' simply-pimply supported boundary condition at loaded edges | 'C-C' clamped-clamped boundary condition at loaded edges | 'S-C' simply-clamped supported boundary condition at loaded edges | 'C-F' clamped-free supported boundary condition at loaded edges | 'C-G' clamped-guided supported boundary condition at loaded edges m_all (np.ndarray): Longitudinal terms for each half-wavelength | m_all[length#] = [longitudinal_num, ...], Longitudinal terms m for all the lengths in cell notation each cell has a vector including the longitudinal terms for this length n_eigs (int): Number of eigenvalues The number of eigenvalues to be determined at length (default=10) sect_props (Sect_Props): Section properties | { | "A": float, | "cx": float, | "cy": float, | "Ixx": float, | "Iyy": float, | "Ixy": float, | "phi": float, | "I11": float, | "I22": float, | "J": float, | "x0": float, | "y0": float, | "Cw": float, | "B1": float, | "B2": float, | "wn": np.ndarray | } Dictionary of section properties of cross-section Returns: signature (np.ndarray): Signature curve | `signature[length#] = load_factor` curve (np.ndarray): buckling curve (load factor) for each length | `curve[length#] = [mode1_load_factor, mode2_load_factor, ...]` shapes (np.ndarray): mode shapes for each length | `shapes[length#] = [disp_mode1, disp_mode2, ...]` Each `disp_*` is an array of displacements for each node in the section .. py:function:: strip_new(props: Dict[str, Dict[str, float]], nodes: pycufsm._types.ArrayLike, elements: Sequence[pycufsm._types.New_Element], yield_force: Optional[pycufsm._types.Yield_Force] = None, forces: Optional[pycufsm._types.Forces] = None, sect_props: Optional[pycufsm._types.Sect_Props] = None, lengths: Optional[Union[pycufsm._types.ArrayLike, set, Dict[float, pycufsm._types.ArrayLike]]] = None, node_props: Optional[Dict[Union[Literal['all'], int], pycufsm._types.New_Node_Props]] = None, springs: Optional[Sequence[pycufsm._types.New_Spring]] = None, constraints: Optional[Sequence[pycufsm._types.New_Constraint]] = None, analysis_config: Optional[pycufsm._types.Analysis_Config] = None, cfsm_config: Optional[pycufsm._types.Cfsm_Config] = None) -> Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray] Converts new format of inputs to old (original CUFSM) format Args: props (Dict[str, Dict[str, float]]): Material properties | `{"mat_name": {E_x: float, E_y: float, nu_x: float, nu_y: float, G_bulk: float}, ...}` | or | `{"mat_name": {E: float, nu: float}}` The latter option assumes an isotropic material. nodes (ArrayLike): Nodal coordinates | `[[x, y, stress], ...]` | or | `[[x, y], ...]` The latter option assumes that the stress will be set using Note that any node numbers used in later inputs refer to the **index** of the node in this `nodes` array, with the first node being node number 0. elements (Sequence[New_Element]): Element connectivity and properties | [{ | `nodes: "all"|List[int],` | `t: float,` | `mat: str` | )]. elements["nodes"]: `nodes: "all"` is a special indicator that all nodes should be connected sequentially. If `nodes` is given as an array, any number of nodal indices may be listed in order elements["t"]: Material thickness elements["mat"]: material name as a string yield_force (Optional[Yield_Force]): Single yield force to apply to section. | { | force: "Mxx"|"Myy"|"M11"|"M22"|"P", | direction: "Pos"|"Neg"|"+"|"-", | f_y: float, | restrain: bool, | offset: ArrayLike | } Either this or 'forces' must be set, or stresses must be set manually in `nodes`. yield_force["restrain"]: Note that 'restrain' only affects "Mxx" or "Myy" forces, and then only for sections in which the principal axes are no aligned with the geometric axes (such as Z sections) yield_force["offset"]: | `[x_offset, y_offset]` Offset from the (0,0) coordinate used in calculating section properties and the (0,0) coordinate used to define the nodal coordinates. This may commonly differ by thickness/2, for example, if an external section properties calculator is used forces (Optional[Forces]): Specific forces to apply to the section. | { | 'P': float, | 'Mxx': float, | 'Myy': float, | 'M11': float, | 'M22': float, | 'restrain': bool, | 'offset': ArrayLike | } forces["restrain"]: Note that 'restrain' only affects "Mxx" or "Myy" forces, and then only for sections in which the principal axes are no aligned with the geometric axes (such as Z sections) forces["offset"]: | `[x_offset, y_offset]` Offset from the (0,0) coordinate used in calculating section properties and the (0,0) coordinate used to define the nodal coordinates. This may commonly differ by thickness/2, for example, if an external section properties calculator is used Either this or 'yield_force' must be set, or stresses must be set manually in `nodes`. sect_props (Optional[Sect_Props]): Section properties | { | "A": float, | "cx": float, | "cy": float, | "Ixx": float, | "Iyy": float, | "Ixy": float, | "phi": float, | "I11": float, | "I22": float, | "J": float, | "x0": float, | "y0": float, | "Cw": float, | "B1": float, | "B2": float, | "wn": np.ndarray | } Dictionary of section properties of cross-section. If None, section properties will be calculated using the included CUTWP based on the geometry defined by `nodes` and `elements`, and the material properties defined in `props`. lengths (Optional[Union[ArrayLike, set, Dict[float, ArrayLike]]]): Half-wavelengths for analysis | `[length1, length2, ...]` | or | `{length1: List[int], length2: List[int], ...} If given as a simple array, then the longitudinal m term will be taken as `[1]` for each half-wavelength (which is normally what you want for a signature curve analysis). If given as a dictionary, then the longitudinal m terms must be set to an array with appropriate values. If None, then lengths will be taken as the recommended lengths based on the geometry of the section, and the longitudinal m terms will be taken as `[1]` for each length. node_props (Optional[Dict[Union[Literal["all", int], New_Node_Props]]): Nodal DOF inclusion | { | node_#|"all": { | dof_x: bool, | dof_y: bool, | dof_z: bool, | dof_q: bool, | } | } Defaults to None, and taken as all DOFs included if so. Any DOFs set to false will be taken as fully constrained to ground springs (Optional[Sequence[New_Spring]]): Definition of any springs in cross-section | [{ | node: int, | k_x: float, | k_y: float, | k_z: float, | k_q: float, | k_type: "foundation"|"node_pair"|"total", | node_pair: int, | discrete: bool, | y: float, | }, ...] `k_type` is the stiffness type. `node_pair` and `y` keys are only required if the `k_type` or `discrete` options are set to require them. Defaults to None. constraints (Optional[Sequence[New_Constraint]]): Definition of any constraints in section | [{ | elim_node: int, | elim_dof: "x"|"y"|"z"|"q", | coeff: float, | keep_node: int, | keep_dof: "x"|"y"|"z"|"q" | }, ...] `"q"` is the twist DOF. Each constraint takes the form of `elim_dof = coeff * keep_dof`. Defaults to None. analysis_config (Optional[Analysis_Config]): Configuration options for any analysis | { | B_C: "S-S"|"C-C"|"S-C"|"C-F"|"C-G", | n_eigs: int | } Defaults to None, and taken as `{B_C: "S-S", n_eigs: 10}` if so. analysis_config["B_C"]: Boundary condition types (at loaded edges): | 'S-S' simple-simple | 'C-C' clamped-clamped | 'S-C' simple-clamped | 'C-F' clamped-free | 'C-G' clamped-guided cfsm_config (Optional[Cfsm_Config]): Configuration options for cFSM (constrained modes) | { | glob_modes: list(int), | dist_modes: list(int), | local_modes: list(int), | other_modes: list(int), | null_space: "ST"|"K_global"|"Kg_global"|"vector", | normalization: "none"|"vector"|"strain_energy"|"work", | coupled: bool, | orthogonality: "natural"|"modal_axial"|"modal_load" } Defaults to None, in which case no cFSM analysis is performed analysis_config["*_modes"]: list of 1's (inclusion) and 0's (exclusion) for each mode from the analysis analysis_config["null_space"]: | "ST": ST basis | "K_global": null space of GDL with respect to K_global | "Kg_global": null space of GDL with respect to Kg_global | "vector": null space of GDL in vector sense analysis_config["normalization"]: Type of normalization If any is performed. analysis_config["coupled"]: basis for general boundary conditions | uncoupled basis = the basis will be block diagonal | coupled basis = the basis is fully spanned analysis_config["orthogonality"]: natural basis vs modal basis | "natural": natural basis | "modal_axial": modal basis, axial orthogonality | "modal_load": modal basis, load dependent orthogonality Returns: signature (np.ndarray): Signature curve | `signature[length#] = load_factor` curve (np.ndarray): buckling curve (load factor) for each length | `curve[length#] = [mode1_load_factor, mode2_load_factor, ...]` shapes (np.ndarray): mode shapes for each length | `shapes[length#] = [disp_mode1, disp_mode2, ...]` Each `disp_*` is an array of displacements for each node in the section nodes_stressed: Nodal coordinates with stresses | `[[x, y, stress], ...]` lengths: Half-wavelengths used in analysis | `[length1, length2, ...]` .. py:function:: signature_ss(props: numpy.ndarray, nodes: numpy.ndarray, elements: numpy.ndarray, i_GBT_con: pycufsm._types.GBT_Con, sect_props: pycufsm._types.Sect_Props, lengths: numpy.ndarray) -> Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray] generate the signature curve solution, part 2: actually solve the signature curve Args: props (np.ndarray): standard parameter nodes (np.ndarray): standard parameter elements (np.ndarray): standard parameter i_GBT_con (GBT_Con): cFSM configuration options sect_props (Sect_Props): section properties lengths (np.ndarray): half-wavelengths Returns: signature: signature curve, curve: all the curve results, shapes: deformed shapes at each point (function originally in helpers; moved to fsm because it drives entire fsm analyses) Z. Li, July 2010 (last modified) .. py:function:: m_recommend(props: numpy.ndarray, nodes: numpy.ndarray, elements: numpy.ndarray, sect_props: pycufsm._types.Sect_Props, length_append: Optional[float] = None, n_lengths: int = 50, lengths: Optional[numpy.ndarray] = None) -> Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray] Suggested longitudinal terms are calculated based on the characteristic half-wave lengths of local, distortional, and global buckling from the signature curve. Args: props (np.ndarray): standard parameter nodes (np.ndarray): standard parameter elements (np.ndarray): standard parameter sect_props (Sect_Props): section properties length_append (Optional[float], optional): any additional half-wavelength to include. Defaults to None. n_lengths (int, optional): number of half-wavelengths. Defaults to 50. lengths (Optional[np.ndarray], optional): specific half-wavelengths to use. Defaults to None. Returns: _type_: _description_ (function originally in helpers; moved to fsm because it drives entire fsm analyses) Z. Li, Oct. 2010