pycufsm.solve.cfsm ================== .. py:module:: pycufsm.solve.cfsm Functions --------- .. autoapisummary:: pycufsm.solve.cfsm.base_column pycufsm.solve.cfsm.base_update pycufsm.solve.cfsm.mode_select pycufsm.solve.cfsm.constr_user pycufsm.solve.cfsm.mode_constr pycufsm.solve.cfsm.y_dofs pycufsm.solve.cfsm.base_vectors pycufsm.solve.cfsm.constr_xz_y pycufsm.solve.cfsm.constr_planar_xz pycufsm.solve.cfsm.constr_yd_yg pycufsm.solve.cfsm.constr_ys_ym pycufsm.solve.cfsm.constr_yu_yd pycufsm.solve.cfsm.base_properties pycufsm.solve.cfsm.meta_elems pycufsm.solve.cfsm.mode_nr pycufsm.solve.cfsm.dof_ordering pycufsm.solve.cfsm.classify pycufsm.solve.cfsm.mode_class pycufsm.solve.cfsm.node_class Module Contents --------------- .. py:function:: base_column(nodes_base: numpy.ndarray, elements: numpy.ndarray, props: numpy.ndarray, length: float, B_C: str, m_a: numpy.ndarray, el_props: numpy.ndarray, node_props: numpy.ndarray, n_main_nodes: int, n_corner_nodes: int, n_sub_nodes: int, n_global_modes: int, n_dist_modes: int, n_local_modes: int, dof_perm: numpy.ndarray, r_x: numpy.ndarray, r_z: numpy.ndarray, r_ys: numpy.ndarray, d_y: numpy.ndarray) -> numpy.ndarray this routine creates base vectors for a column with length length for all the specified longitudinal terms in m_a assumptions orthogonalization is not performed unless the user wants orthogonalization is done by solving the eigen-value problem within each sub-space normalization is not done Args: nodes_base (np.ndarray): standard nodes parameter, but with zero stresses elements (np.ndarray): standard parameter props (np.ndarray): standard parameter length (float): half-wavelength B_C (str): ['S-S'] a string specifying boundary conditions 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_bulk' clamped-guided supported boundary condition at loaded edges m_a (np.ndarray): longitudinal terms (half-wave numbers) el_props (np.ndarray): standard parameter node_props (np.ndarray): _description_ n_main_nodes (int): _description_ n_corner_nodes (int): _description_ n_sub_nodes (int): _description_ n_global_modes (int): _description_ n_dist_modes (int): _description_ n_local_modes (int): _description_ dof_perm (np.ndarray): _description_ r_x (np.ndarray): _description_ r_z (np.ndarray): _description_ r_ys (np.ndarray): _description_ d_y (np.ndarray): _description_ Returns: b_v_l (np.ndarray): base vectors (each column corresponds to a certain mode) assemble for each half-wave number m_i on its diagonal b_v_l = diag(b_v_m) for each half-wave number m_i, b_v_m columns 1..n_global_modes: global modes columns (n_global_modes+1)..(n_global_modes+n_dist_modes): dist. modes columns (n_global_modes+n_dist_modes+1) ..(n_global_modes+n_dist_modes+n_local_modes): local modes columns (n_global_modes+n_dist_modes+n_local_modes+1)..n_dof: other modes n_global_modes, n_dist_modes, n_local_modes - number of G_bulk, D, L modes, respectively S. Adany, Aug 28, 2006 B. Schafer, Aug 29, 2006 Z. Li, Dec 22, 2009 Z. Li, June 2010 .. py:function:: base_update(GBT_con: pycufsm._types.GBT_Con, b_v_l: numpy.ndarray, length: float, m_a: numpy.ndarray, nodes: numpy.ndarray, elements: numpy.ndarray, props: numpy.ndarray, n_global_modes: int, n_dist_modes: int, n_local_modes: int, B_C: str, el_props: numpy.ndarray) -> numpy.ndarray this routine optionally makes orthogonalization and normalization of base vectors assumptions orthogonalization is done by solving the EV problem for each sub-space three options for normalization is possible, set by 'GBT_con['norm']' parameter Args: GBT_con (GBT_Con): GBT_con['o_space'] - by GBT_con, 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'] - by GBT_con, 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'] - by GBT_con, 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'] - by GBT_con, natural basis vs modal basis 1: natural basis 2: modal basis, axial orthogonality 3: modal basis, load dependent orthogonality b_v_l (np.ndarray): natural base vectors for length (each column corresponds to a certain mode) for each half-wave number m_i columns 1..n_global_modes: global modes columns (n_global_modes+1)..(n_global_modes+n_dist_modes): dist. modes columns (n_global_modes+n_dist_modes+1) ..(n_global_modes+n_dist_modes+n_local_modes): local modes columns (n_global_modes+n_dist_modes+n_local_modes+1)..n_dof_m: other modes length (float): _description_ m_a (np.ndarray): _description_ nodes (np.ndarray): _description_ elements (np.ndarray): _description_ props (np.ndarray): _description_ n_global_modes (int): _description_ n_dist_modes (int): _description_ n_local_modes (int): _description_ B_C (str): _description_ el_props (np.ndarray): _description_ Returns: b_v (np.ndarray): output base vectors (maybe natural, orthogonal or normalized, depending on the selected options) S. Adany, Oct 11, 2006 Z. Li modified on Jul 10, 2009 Z. Li, June 2010 .. py:function:: mode_select(b_v: numpy.ndarray, n_global_modes: int, n_dist_modes: int, n_local_modes: int, GBT_con: pycufsm._types.GBT_Con, n_dof_m: int, m_a: numpy.ndarray) -> numpy.ndarray this routine selects the required base vectors b_v_red forms a reduced space for the calculation, including the selected modes only b_v_red itself is the final constraint matrix for the selected modes note: for all if_* indicator: 1 if selected, 0 if eliminated Args: b_v (np.ndarray): base vectors (each column corresponds to a certain mode) columns 1..n_global_modes: global modes columns (n_global_modes+1)..(n_global_modes+n_dist_modes): dist. modes columns (n_global_modes+n_dist_modes+1) ..(n_global_modes+n_dist_modes+n_local_modes): local modes columns (n_global_modes+n_dist_modes+n_local_modes+1)..n_dof: other modes n_global_modes (int): _description_ n_dist_modes (int): _description_ n_local_modes (int): _description_ GBT_con (GBT_Con): GBT_con['glob'] - indicator which global modes are selected GBT_con['dist'] - indicator which dist. modes are selected GBT_con['local'] - indicator whether local modes are selected GBT_con['other'] - indicator whether other modes are selected n_dof_m (int): 4*n_nodes, total DOF for a single longitudinal term m_a (np.ndarray): _description_ Returns: b_v_red (np.ndarray): reduced base vectors (each column corresponds to a certain mode) S. Adany, Mar 22, 2004 BWS May 2004 modifed on Jul 10, 2009 by Z. Li for general B_C Z. Li, June 2010 .. py:function:: constr_user(nodes: numpy.ndarray, constraints: numpy.ndarray, m_a: numpy.ndarray) -> numpy.ndarray this routine creates the constraints matrix, r_user_matrix, as defined by the user Args: nodes (np.ndarray): same as elsewhere throughout this program constraints (np.ndarray): same as 'constraints' throughout this program m_a (np.ndarray): longitudinal terms to be included for this length Returns: r_user_matrix (np.ndarray): the constraints matrix (in other words: base vectors) so that displ_orig = r_user_matrix * displ_new S. Adany, Feb 26, 2004 Z. Li, Aug 18, 2009 for general b.c. Z. Li, June 2010 .. py:function:: mode_constr(nodes: numpy.ndarray, elements: numpy.ndarray, node_props: numpy.ndarray, main_nodes: numpy.ndarray, meta_elements: numpy.ndarray) -> Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray] this routine creates the constraint matrices necessary for mode separation/classification for each specified half-wave number m_i assumptions GBT-like assumptions are used the cross-section must not be closed and must not contain closed parts must check whether 'Warp' works well for any open section !!! notes: m-el_i-? is positive if the starting nodes of m-el_i-? coincides with the given m-nodes, otherwise negative nodes types: 1-corner, 2-edge, 3-sub sub-nodes numbers are the original one, of course Args: nodes (np.ndarray): standard parameter elements (np.ndarray): standard parameter node_props (np.ndarray): array of [original nodes nr, new nodes nr, nr of adj elements, nodes type] main_nodes (np.ndarray): array of [nr, x, z, orig nodes nr, nr of adj meta-elements, m_i-el_i-1, m_i-el_i-2, ...] meta_elements (np.ndarray): array of [nr, main-nodes-1, main-nodes-2, nr of sub-nodes, sub-no-1, sub-nod-2, ...] Returns: r_x (np.ndarray): constaint matrices for x dofs r_z (np.ndarray): constaint matrices for z dofs r_ys (np.ndarray): constaint matrices for y dofs of sub-nodes r_yd (np.ndarray): constaint matrices for y dofs of main nodes for distortional buckling r_ys (np.ndarray): constaint matrices for y dofs of indefinite (?independent?) main nodes S. Adany, Mar 10, 2004 Z. Li, Jul 10, 2009 .. py:function:: y_dofs(nodes: numpy.ndarray, elements: numpy.ndarray, main_nodes: numpy.ndarray, n_main_nodes: int, n_dist_modes: int, r_yd: numpy.ndarray, r_ud: numpy.ndarray, sect_props: pycufsm._types.Sect_Props, el_props: numpy.ndarray) -> Tuple[numpy.ndarray, int] this routine creates y-DOFs of main nodes for global buckling and distortional buckling, however: only involves single half-wave number m_i assumptions GBT-like assumptions are used the cross-section must not be closed and must not contain closed parts Args: nodes (np.ndarray): standard parameter elements (np.ndarray): standard parameter main_nodes (np.ndarray): nodes of 'meta' cross-section n_main_nodes (int): _description_ n_dist_modes (int): _description_ r_yd (np.ndarray): constrain matrices r_ud (np.ndarray): constrain matrices sect_props (Sect_Props): _description_ el_props (np.ndarray): _description_ Returns: d_y (np.ndarray): y-DOFs of main nodes for global buckling and distortional buckling (each column corresponds to a certain mode) S. Adany, Mar 10, 2004, modified Aug 29, 2006 Z. Li, Dec 22, 2009 .. py:function:: base_vectors(d_y: numpy.ndarray, elements: numpy.ndarray, el_props: numpy.ndarray, length: float, m_i: float, node_props: numpy.ndarray, n_main_nodes: int, n_corner_nodes: int, n_sub_nodes: int, n_global_modes: int, n_dist_modes: int, n_local_modes: int, r_x: numpy.ndarray, r_z: numpy.ndarray, r_p: numpy.ndarray, r_ys: numpy.ndarray, dof_perm: numpy.ndarray) -> numpy.ndarray this routine creates the base vectors for global, dist., local and other modes assumptions GBT-like assumptions are used the cross-section must not be closed and must not contain closed parts must check whether 'Warp' works well for any open section !!! Args: d_y (np.ndarray): _description_ elements (np.ndarray): standard parameter el_props (np.ndarray): standard parameter length (float): element length m_i (float): number of half-waves node_props (np.ndarray): some properties of the nodes n_main_nodes (int): number of nodes of given type n_corner_nodes (int): number of nodes of given type n_sub_nodes (int): number of nodes of given type n_global_modes (int): number of given modes n_dist_modes (int): number of given modes n_local_modes (int): number of given modes r_x (np.ndarray): constraint matrix r_z (np.ndarray): constraint matrix r_p (np.ndarray): constraint matrix r_ys (np.ndarray): constraint matrix dof_perm (np.ndarray):permutation matrix to re-order the DOFs Returns: np.ndarray: _description_ S. Adany, Mar 10, 2004, modified Aug 29, 2006 Z. Li, Dec 22, 2009 .. py:function:: constr_xz_y(main_nodes: numpy.ndarray, meta_elements: numpy.ndarray) -> Tuple[numpy.ndarray, numpy.ndarray] this routine creates the constraint matrix, Rxz, that defines relationship between x, z displacements DOFs [for internal main nodes, referred also as corner nodes] and the longitudinal y displacements DOFs [for all the main nodes] if GBT-like assumptions are used to make this routine length-independent, Rxz is not multiplied here by (1/k_m), thus it has to be multiplied outside of this routine! additional assumption: cross section is opened! note: m-el_i-? is positive if the starting nodes of m-el_i-? coincides with the given m-nodes, otherwise negative Args: main_nodes (np.ndarray): array of [nr, x, z, orig nodes nr, nr of adj meta-elements, m-el_i-1, m-el_i-2, ...] meta_elements (np.ndarray): array of [nr, main-nodes-1, main-nodes-2, nr of sub-nodes, sub-no-1, sub-nod-2, ...] Returns: r_x (np.ndarray): x dof restraints r_z (np.ndarray): z dof restraints S. Adany, Feb 05, 2004 .. py:function:: constr_planar_xz(nodes: numpy.ndarray, elements: numpy.ndarray, props: numpy.ndarray, node_props: numpy.ndarray, dof_perm: numpy.ndarray, m_i: float, length: float, B_C: str, el_props: numpy.ndarray) -> numpy.ndarray this routine creates the constraint matrix, r_p, that defines relationship between x, z DOFs of any non-corner nodes + teta DOFs of all nodes, and the x, z displacements DOFs of corner nodes if GBT-like assumptions are used Args: nodes (np.ndarray): standard parameter elements (np.ndarray): standard parameter props (np.ndarray): standard parameter node_props (np.ndarray): array of [original nodes nr, new nodes nr, nr of adj elements, nodes type] dof_perm (np.ndarray): permutation matrix, so that (orig-displacements-vect) = (dof_perm) � (new-displacements - vector) m_i (float): _description_ length (float): element length B_C (str): standard parameter el_props (np.ndarray): standard parameter Returns: r_p (np.ndarray):constraint matrix, r_p, that defines relationship between x, z DOFs of any non-corner nodes + teta DOFs of all nodes, and the x, z displacements DOFs of corner nodes S. Adany, Feb 06, 2004 Z. Li, Jul 10, 2009 .. py:function:: constr_yd_yg(nodes: numpy.ndarray, elements: numpy.ndarray, node_props: numpy.ndarray, r_ys: numpy.ndarray, n_main_nodes: int) -> numpy.ndarray this routine creates the constraint matrix, r_yd, that defines relationship between base vectors for distortional buckling, and base vectors for global buckling, but for y DOFs of main nodes only Args: nodes (np.ndarray): standard parameter elements (np.ndarray): standard parameter node_props (np.ndarray): array of [original nodes nr, new nodes nr, nr of adj elements, nodes type] r_ys (np.ndarray): constraint matrix, see function 'constr_ys_ym' n_main_nodes (int): nr of main nodes Returns: r_yd (np.ndarray): constraint matrix for y DOFs in distortional buckling S. Adany, Mar 04, 2004 .. py:function:: constr_ys_ym(nodes: numpy.ndarray, main_nodes: numpy.ndarray, meta_elements: numpy.ndarray, node_props: numpy.ndarray) -> numpy.ndarray this routine creates the constraint matrix, r_ys, that defines relationship between y DOFs of sub-nodes, and the y displacements DOFs of main nodes by linear interpolation Args: nodes (np.ndarray): standard parameter main_nodes (np.ndarray): array of [nr, x, z, orig nodes nr, nr of adj meta-elements, m-el_i-1, m-el_i-2, ...] meta_elements (np.ndarray): array of [nr, main-nodes-1, main-nodes-2, nr of sub-nodes, sub-no-1, sub-nod-2, ...] node_props (np.ndarray): array of [original nodes nr, new nodes nr, nr of adj elements, nodes type] Returns: r_ys (np.ndarray): constraint matrix for y DOFs of sub-nodes S. Adany, Feb 06, 2004 .. py:function:: constr_yu_yd(main_nodes: numpy.ndarray, meta_elements: numpy.ndarray) -> numpy.ndarray this routine creates the constraint matrix, r_ud, that defines relationship between y displacements DOFs of indefinite main nodes and the y displacements DOFs of definite main nodes (definite main nodes = those main nodes which unambiguously define the y displacements pattern indefinite main nodes = those nodes the y DOF of which can be calculated from the y DOF of definite main nodes note: for open sections with one single branch only there are no indefinite nodes) important assumption: cross section is opened! note: m-el_i-? is positive if the starting nodes of m-el_i-? coincides with the given m-nodes, otherwise negative Args: main_nodes (np.ndarray): array of [nr, x, z, orig nodes nr, nr of adj meta-elements, m-el_i-1, m-el_i-2, ...] meta_elements (np.ndarray): array of [nr, main-nodes-1, main-nodes-2, nr of sub-nodes, sub-no-1, sub-nod-2, ...] Returns: r_ud (np.ndarray): constraint matrix between definite and indefinite main nodes S. Adany, Mar 10, 2004 .. py:function:: base_properties(nodes: numpy.ndarray, elements: numpy.ndarray) -> Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, int, int, int, int, int, numpy.ndarray] this routine creates all the data for defining the base vectors from the cross section properties Args: nodes (np.ndarray): standard parameters elements (np.ndarray): standard parameters Returns: main_nodes (np.ndarray): array of [nr, x, z, orig nodes nr, nr of adj meta-elements, m-el_i-1, m-el_i-2, ...] meta_elements (np.ndarray): array of [nr, main-nodes-1, main-nodes-2, nr of sub-nodes, sub-no-1, sub-nod-2, ...] node_props (np.ndarray): array of [original nodes nr, new nodes nr, nr of adj elements, nodes type] n_main_nodes (int): number of main nodes n_corner_nodes (int): number of corner nodes n_sub_nodes (int): number of sub-nodes n_dist_modes (int): number of distortional modes n_local_modes (int): number of local modes dof_perm (np.ndarray): permutation matrix, so that (orig-displacements-vect) = (dof_perm) � (new-displacements-vector) S. Adany, Aug 28, 2006 B. Schafer, Aug 29, 2006 Z. Li, Dec 22, 2009 .. py:function:: meta_elems(nodes: numpy.ndarray, elements: numpy.ndarray) -> Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray] this routine re-organises the basic input data to eliminate internal subdividing nodes to form meta-elements (corner-to-corner or corner-to-free edge) to identify main nodes (corner nodes and free edge nodes) important assumption: cross section is opened! note: m-el_i-? is positive if the starting nodes of m-el_i-? coincides with the given m-nodes, otherwise negative nodes types: 1-corner, 2-edge, 3-sub sub-nodes numbers are the original ones, of course Args: nodes (np.ndarray): standard parameter elements (np.ndarray): standard parameter Returns: main_nodes (np.ndarray): main nodes (i.e. corner and free edge nodes) array of [nr, x, z, orig nodes nr, nr of adj meta-elements, m-el_i-1, m-el_i-2, ...]? meta_elements (np.ndarray): elements connecting main nodes array of [nr, main-nodes-1, main-nodes-2, nr of sub-nodes, sub-no-1, sub-nod-2, ...] node_props (np.ndarray): properties of main nodes array of [original nodes nr, new nodes nr, nr of adj elements, nodes type] S. Adany, Feb 06, 2004 .. py:function:: mode_nr(n_main_nodes: int, n_corner_nodes: int, n_sub_nodes: int, main_nodes: numpy.ndarray) -> Tuple[int, int] this routine determines the number of distortional and local buckling modes if GBT-like assumptions are used Args: n_main_nodes (int): number of main nodes n_corner_nodes (int): number of corner nodes n_sub_nodes (int): number of sub nodes main_nodes (np.ndarray): array of [nr, x, z, orig nodes nr, nr of adj meta-elements, m-el_i-1, m-el_i-2, ...] Returns: n_dist_modes (int): number of distortional modes n_local_modes (int): number of local modes S. Adany, Feb 09, 2004 .. py:function:: dof_ordering(node_props: numpy.ndarray) -> numpy.ndarray this routine re-orders the DOFs, according to the need of forming shape vectors for various buckling modes notes: (1) nodes types: 1-corner, 2-edge, 3-sub (2) the re-numbering of long. displacements. DOFs of main nodes, which may be necessary for dist. buckling, is not included here but handled separately when forming Ry constraint matrix Args: node_props (np.ndarray): array of [original nodes nr, new nodes nr, nr of adj elements, nodes type] Returns: dof_perm (np.ndarray): permutation matrix, so that (orig-displacements-vect) = (dof_perm) � (new-displacements-vector) S. Adany, Feb 06, 2004 .. py:function:: classify(props: numpy.ndarray, nodes: numpy.ndarray, elements: numpy.ndarray, lengths: numpy.ndarray, shapes: numpy.ndarray, GBT_con: pycufsm._types.GBT_Con, B_C: str, m_all: numpy.ndarray, sect_props: pycufsm._types.Sect_Props) -> List[numpy.ndarray] modal classificaiton Args: props (np.ndarray): [mat_num stiff_x E_y nu_x nu_y G_bulk] 6 x nmats nodes (np.ndarray): [nodes# x z dof_x dof_z dof_y dofrot stress] n_nodes x 8 elements (np.ndarray): [elements# node_i node_j thick mat_num] n_elements x 5 lengths (np.ndarray): lengths to be analysed shapes (np.ndarray): array of mode shapes dof x lengths x mode GBT_con (GBT_Con): _description_ method: method = 1 = vector norm method = 2 = strain energy norm method = 3 = work norm B_C (str): _description_ m_all (np.ndarray): _description_ sect_props (Sect_Props): _description_ Returns: clas (List[np.ndarray]): array of # classification BWS August 29, 2006 modified SA, Oct 10, 2006 Z.Li, June 2010 .. py:function:: mode_class(b_v: numpy.ndarray, displacements: numpy.ndarray, n_global_modes: int, n_dist_modes: int, n_local_modes: int, m_a: numpy.ndarray, n_dof_m: int, GBT_con: pycufsm._types.GBT_Con) -> numpy.ndarray to determine mode contribution in the current displacement Args: b_v (np.ndarray): base vectors (each column corresponds to a certain mode) columns 1..n_global_modes: global modes columns (n_global_modes+1)..(n_global_modes+n_dist_modes): dist. modes columns (n_global_modes+n_dist_modes+1) ..(n_global_modes+n_dist_modes+n_local_modes): local modes columns (n_global_modes+n_dist_modes+n_local_modes+1)..n_dof: other modes displacements (np.ndarray): vector of nodal displacements n_global_modes (int): number of modes n_dist_modes (int): number of modes n_local_modes (int): number of modes m_a (np.ndarray): _description_ n_dof_m (int): _description_ GBT_con (GBT_Con): _description_ GBT_con['couple'] - by GBT_con, 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 Returns: clas_gdlo (np.ndarray): array with the contributions of the modes in percentage elem1: global, elem2: dist, elem3: local, elem4: other S. Adany, Mar 10, 2004 Z. Li, June 2010 .. py:function:: node_class(node_props: numpy.ndarray) -> Tuple[int, int, int] this routine determines how many nodes of the various types exist notes: node types in node_props: 1-corner, 2-edge, 3-sub sub-node numbers are the original one, of course Args: node_props (np.ndarray): array of [original node nr, new node nr, nr of adj elems, node type] Returns: n_main_nodes (int): number of main nodes n_corner_nodes (int): number of corner nodes n_sub_nodes (int): number of sub-nodes S. Adany, Feb 09, 2004