Skip to content

计算固体力学结构力学求解器(三维桁架求解器:衔架位移&衔架固有频率)Computational Soild Mechanics Class homework

Notifications You must be signed in to change notification settings

XIANGLONGGUO/SM_Solver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Homework of computational soild mechanics

同学们,下面是计算固体力学编程作业: 编写求解三维桁架或三维刚架静位移、应力以及固有模态的程序。程序语言不限,用A4纸正反面打印,12月14号交。 程序模块包括: 1 结点,单元,材料性质和外载荷输入模块; 2 单元矩阵计算和组装模块; 3 考虑位移边界条件,求解静力问题,并画出结构变形图模块; 4 考虑位移边界条件,求解广义本征值方程,并画出前5阶模态图模块。 requirements:Numpy,matlabplot,Scipy Authod:Guo XL,Wang WH

演示内容

此程序主要用于对桁架结构求解,代码中部分是废弃的

此例子模型对左下角点加全方向约束,右下只有 x 方向没有约束,上方点约束为 z 方向。

这是振动模态图和特征频率(此处可能由于 python 求解广义特征值精度有一定误差)(此模型只有三个模态):

振动模态图和特征频率1
振动模态图和特征频率2
振动模态图和特征频率3
振动模态图和特征频率4

对于此模型进行静力分析:施加 y 方向 1N 的力在上方节点:

这是位移场:

位移场

这是放大 10000 的形变图:

形变图

代码

下面是代码: 主函数:主要是用于导入:此处数据已经被我写入了上面的默认测试样例 main.py:

import math
import numpy as np
from utils import *
#from node import *
from calculate import *

if __name__=="__main__":
    print('Welcome to SM_Solver')
    print('author:GUOxianglong')
    node_list=[[0.0, 0.0, 0.0],[0.01, 0.0, 0.0],[0.005, 0.00866025404, 0.010]]####
    #node_list=[[0.0, 0.0, 0.0],[0.0, 0.33333, 0.0],[0.0,0.666666,0.0],[0.0,1.0,0.0]]
    connect_node=[[0,1],[1,2],[0,2]]####
    dist_list=[]
    l=[]

    Us=[[0,0,0],[0,1,0],[0,2,0],[1,1,0],[1,2,0],[2,2,0]]
    Metal=[70.0, 2750.0, 7.854e-07, 0.0, 0.0, 0.0, 0.0]
    '''connect_node=[[0,1],[1,2],[2,3]]####
    dist_list=[]
    l=[]

    Us=[[0,0,0],[0,1,0],[0,2,0],[3,0,0],[3,1,0],[3,2,0],[1,0,0],[1,2,0],[2,0,0],[2,2,0]]
    Metal=[1, 1e9, 1  , 0.0, 0.0, 0.0, 0.0]'''
    Dict_disp={}
    Lam = {}
    Ke = {}
    Me = {}
    mode=0
    R = []
    while True:
        node_list=convert(node_list)
        connect_node=convert1(connect_node)
        #dist_list=convert(dist_list)
        print('输入calculate来计算')
        print('输入add_node来添加节点')
        print('输入add_connect来添加连接')
        print('输入remove_node来删除节点')
        print('输入add_point来添加节点间的节点')
        print('输入remove_connect来删除连接')
        print('输入remove_point来删除节点间的节点')
        print('输入plot来绘图')
        print('输入mat来输入材料参数')
        print('输入force来添加载荷')
        print('输入c来计算')
        print('输入hz来计算频率')
        print('输入l来输入节点约束')
        print('exit退出')
        #######################################################################
        #Edit the shape of structure

        imput=input("输入操作:")
        if imput=="exit":
            break
        elif imput=="add_node" or imput=="an":
            print("开始添加节点")
            node_list=add_node_utils(node_list)
            for i in range(len(node_list)):
                print(i)
                print(node_list[i])
        elif imput=="remove_node" or imput=="rn":
            print("开始删除节点")
            node_list=remove_node_utils(node_list)
        elif imput=="add_connect" or imput=="ac":
            print("开始添加连接")
            #print('相同节点添加一次力即可')
            connect_node=add_connect_utils(node_list,connect_node)
        elif imput=="add_point" or imput=="ap":
            print("开始添加节点间的节点")
            print('不推荐使用这个功能,推荐多次建立节点,然后连接')
            dist_list=add_point_utils(node_list,connect_node,dist_list)
        elif imput=="remove_connect" or imput=="rc":
            print("开始删除连接")
            connect_node=remove_connect_utils(node_list,connect_node)
        elif imput=="remove_point" or imput=="rp":
            print("开始删除节点间的节点")
            dist_list=remove_point_utils(node_list,connect_node,dist_list)
        elif imput=="plot" or imput=="p":
            print("开始绘图")
            plot(node_list,connect_node)
        #######################################################################
        #create displcements and angle displacements
        elif imput=="mat" or imput=="m":
            mode = int(input('请选择求解桁架还是刚架,桁架请输入0,刚架请输入1\n'))
            Metal = input('请输入材料杨氏模量E,密度p,杆或梁的横截面积A,惯性矩Iz(杆输入0),惯性矩Iy(杆输入0),极惯性矩Ip(杆输入0),剪切模量G(杆输入0)\n格式为E(GPa),p(kg/m^3),A(m^2),Iz(m^4),Iy(m^4),Ip(m^4),G(GPa)\n').split(',')
            Metal = list(map(float,Metal))
            R = []
            while True:
                if mode == 0:
                    if Metal[3] != 0 or Metal[4] != 0 or Metal[5] != 0 or Metal[6] != 0:
                        print('Iz或Iy或Ip不等于0!!!!!')
                        Metal = input('请输入材料杨氏模量E,密度p,杆或梁的横截面积A,惯性矩Iz(杆输入0),惯性矩Iy(杆输入0),极惯性矩Ip(杆输入0),剪切模量G(杆输入0)\n格式为E(GPa),p(kg/m^3),A(m^2),Iz(m^4),Iy(m^4),Ip(m^4),G(GPa)\n').split(',')
                        Metal = list(map(float,Metal))
                    else:
                        print('设置完毕,桁架模式,材料参数如下',Metal)
                        break
                elif mode == 1:
                    print('设置完毕,刚架模式,材料参数如下',Metal)
                    break
                else:
                    print('模式选择错误,请重新选择')
                    mode = int(input('请选择求解桁架还是刚架,桁架请输入0,刚架请输入1\n'))
                    Metal = input('请输入材料杨氏模量E,密度p,杆或梁的横截面积A,惯性矩Iz(杆输入0),惯性矩Iy(杆输入0),极惯性矩Ip(杆输入0),剪切模量G(杆输入0)\n格式为E(GPa),p(kg/m^3),A(m^2),Iz(m^4),Iy(m^4),Ip(m^4),G(GPa)\n').split(',')
                    Metal = list(map(float,Metal))
        elif imput=='force' or imput=='f':
            R=add_force(R,node_list,connect_node,mode)
        elif imput=='l':
            l=get_l(l)
            Us=convert(l)
        elif imput=='calculate' or imput=='c':

            E,D,A,Iz,Iy,Ix,G = (Metal[0],Metal[1],Metal[2],Metal[3],Metal[4],Metal[5],Metal[6])
            for i in range(len(connect_node)):
                node = connect_node[i]
                op = node_list[node[0]]
                ed = node_list[node[1]]
                ele_array = np.array(op)-np.array(ed)
                lenth = np.linalg.norm(ele_array)
            
                if mode == 0:
                    print('衔架')
                    Lam[i] = cal_lam(ele_array,mode)
                    k = np.matrix([[1,-1],[-1,1]],dtype=float)
                    m = np.matrix([[2,1],[1,2]],dtype=float)#一致质量矩阵
                    Ke[i] = np.mat((E*10**9*A/lenth)*k)
                    Me[i] = D*A*lenth*m/6
                elif mode == 1:
                    print('钢架')
                    print(op,ed)
                    enode = np.array(list(map(float,input('请输入任意主平面xy内点的坐标,格式为0,0,0\n').split(','))))-np.array(op)
                    Lam[i] = cal_lam(ele_array,mode,enode)
                    k = np.matrix(np.zeros((12,12),dtype=float))
                    a1,a2,a3,a4,a5,a6,a7,a8 = (E*A/lenth,12*E*Iz/lenth**3,6*E*Iz/lenth**2,12*E*Iy/lenth**3,-6*E*Iy/lenth**2,G*Ix/lenth,4*E*Iy/lenth,4*E*Iz/lenth)
                    k[0,0],k[1,1],k[5,1],k[2,2],k[4,2],k[3,3],k[4,4],k[5,5] = (a1,a2,a3,a4,a5,a6,a7,a8)
                    k[6:12,6:12] = k[0:6,0:6]
                    k[11,7],k[10,8] = (-a3,-a5)
                    k[6,0],k[7,1],k[11,1],k[8,2],k[10,2],k[9,3],k[8,4],k[10,4],k[7,5],k[11,5] = (-a1,-a2,a3,-a4,a5,-a6,-a5,-a5/3,-a3,a8/2)
                    k += k.T - np.diag(k.diagonal())
                    Ke[i] = np.matrix(k,dtype=float)
                    m = np.matrix(np.zeros((12,12),dtype=float))
                    m[0,0],m[1,1],m[5,1],m[2,2],m[4,2],m[3,3],m[4,4],m[5,5] = (140,156,22*lenth,156,-22*lenth,140*Ix/A,4*lenth**2,4*lenth**2)
                    m[6:12,6:12] = m[0:6,0:6]
                    m[11,7],m[10,8] = (-22*lenth,22*lenth)
                    m[6,0],m[7,1],m[11,1],m[8,2],m[10,2],m[9,3],m[8,4],m[10,4],m[7,5],m[11,5] = (70,54,-13*lenth,54,13*lenth,70*Ix/A,-13*lenth,-3*lenth**2,13*lenth,-3*lenth**2)
                    m += m.T - np.diag(m.diagonal())
                    Me[i] = np.matrix(D*A*lenth*m/420,dtype=float)
            u_and_fw_out = u_and_fw(mode,node_list,R,connect_node,Lam,Ke,Me)
            Uw = u_and_fw_out[0]#位移列向量
            Fw = u_and_fw_out[1]#载荷列向量
            K_an_M_out = cal_k_or_m(mode,node_list,connect_node,Lam,Ke,Me)
            Kw = K_an_M_out[0]
            Mw = K_an_M_out[1]
            
            Uw = cal(Fw,Kw,mode,node_list,Us)
            print(Uw)
            s=int(input('请输入放大倍数:'))
            #s=50000000
            draw_strain(node_list,connect_node,Uw,mode,s)
        
        elif imput=='hz':

            E,D,A,Iz,Iy,Ix,G = (Metal[0],Metal[1],Metal[2],Metal[3],Metal[4],Metal[5],Metal[6])
            for i in range(len(connect_node)):
                node = connect_node[i]
                op = node_list[node[0]]
                ed = node_list[node[1]]
                ele_array = np.array(op)-np.array(ed)
                lenth = np.linalg.norm(ele_array)
            
                if mode == 0:
                    print('衔架')
                    Lam[i] = cal_lam(ele_array,mode)
                    k = np.matrix([[1,-1],[-1,1]],dtype='float64')
                    m = np.matrix([[2,1],[1,2]],dtype='float64')#一致0
                    #质量矩阵
                    Ke[i] = np.mat((E*10**9*A/lenth)*k)
                    Me[i] = D*A*lenth*m/6

                elif mode == 1:
                    print('钢架')
                    print(op,ed)
                    enode = np.array(list(map(float,input('请输入任意主平面xy内点的坐标,格式为0,0,0\n').split(','))))-np.array(op)
                    Lam[i] = cal_lam(ele_array,mode,enode)
                    k = np.matrix(np.zeros((12,12),dtype='float64'))
                    a1,a2,a3,a4,a5,a6,a7,a8 = (E*A/lenth,12*E*Iz/lenth**3,6*E*Iz/lenth**2,12*E*Iy/lenth**3,-6*E*Iy/lenth**2,G*Ix/lenth,4*E*Iy/lenth,4*E*Iz/lenth)
                    k[0,0],k[1,1],k[5,1],k[2,2],k[4,2],k[3,3],k[4,4],k[5,5] = (a1,a2,a3,a4,a5,a6,a7,a8)
                    k[6:12,6:12] = k[0:6,0:6]
                    k[11,7],k[10,8] = (-a3,-a5)
                    k[6,0],k[7,1],k[11,1],k[8,2],k[10,2],k[9,3],k[8,4],k[10,4],k[7,5],k[11,5] = (-a1,-a2,a3,-a4,a5,-a6,-a5,-a5/3,-a3,a8/2)
                    k += k.T - np.diag(k.diagonal())
                    Ke[i] = np.matrix(k,dtype=float)
                    m = np.matrix(np.zeros((12,12),dtype='float64'))
                    m[0,0],m[1,1],m[5,1],m[2,2],m[4,2],m[3,3],m[4,4],m[5,5] = (140,156,22*lenth,156,-22*lenth,140*Ix/A,4*lenth**2,4*lenth**2)
                    m[6:12,6:12] = m[0:6,0:6]
                    m[11,7],m[10,8] = (-22*lenth,22*lenth)
                    m[6,0],m[7,1],m[11,1],m[8,2],m[10,2],m[9,3],m[8,4],m[10,4],m[7,5],m[11,5] = (70,54,-13*lenth,54,13*lenth,70*Ix/A,-13*lenth,-3*lenth**2,13*lenth,-3*lenth**2)
                    m += m.T - np.diag(m.diagonal())
                    Me[i] = np.matrix(D*A*lenth*m/420,dtype='float64')
            u_and_fw_out = u_and_fw(mode,node_list,R,connect_node,Lam,Ke,Me)
            Uw = u_and_fw_out[0]#位移列向量
            Fw = u_and_fw_out[1]#载荷列向量
            K_an_M_out = cal_k_or_m(mode,node_list,connect_node,Lam,Ke,Me)
            Kw = K_an_M_out[0]
            Mw = K_an_M_out[1]
            
            Uss=[None]*len(node_list)
            for i in range(len(node_list)):
                Uss[i]=[0,0,0]
            for j in Us:
                i=int(j[0])
                if j[1]==0:
                    Uss[i][0]=1
                elif j[1]==1:
                    Uss[i][1]=1
                elif j[1]==2:
                    Uss[i][2]=1
            #import numpy as np
            import scipy.linalg as sl
            def delete(K, M, NP=len(node_list), NRR=Uss, NF=3):
                DK = K.copy()
                DM = M.copy()
                count = []

                for i in range(NP):
                    for j in range(NF):
                        print(i,j)
                        if NRR[i][j] == 1:
                            count.append(i * NF + j)

                # 将 count 转换为 NumPy 数组以便于索引
                count = np.array(count)

                # 删除行和列
                DK = np.delete(DK, count, axis=0)
                DK = np.delete(DK, count, axis=1)

                DM = np.delete(DM, count, axis=0)
                DM = np.delete(DM, count, axis=1)

                return DK, DM

            # 示例用法:
            # 假设在调用函数之前已经定义了 Node、Uss 和 NP 的值
            # K 和 M 是你的二维 NumPy 数组
            # DK, DM = delete(K, M, len(Node), Uss, NP)

            DK,DM=delete(Kw, Mw)
            print('-------------------------Kw-------------------------')
            print(Kw)
            print('-------------------------Mw-------------------------')
            print(Mw)
            e,v = sl.eig(DK,DM)

            #e=np.sqrt(e)
            print('-------------------------e-------------------------')
            print(e)
            print('-------------------------v-------------------------')
            print(v)
            #57924 105610 139080
            #print(la.norm(DK-DM*e[0]))
            

            print('-------------------------omega-------------------------')
            e=np.sqrt(e)
            print(e)
            print('-------------------------Uw-------------------------')
            m=0
            for i in range(len(v)):
                Uw=[None]*3*len(node_list)
                n=0
                for i in range(len(node_list)):
                        for j in range(3):
                            #print(i,j)
                            if Uss[i][j] == 1:
                                Uw[i * 3 + j]=0
                for i in range(len(Uw)):
                    if Uw[i] == None:
                        Uw[i]=v[m][n]
                        n+=1
                m+=1
                s=int(input('请输入放大倍数:'))
                #s=0.001
                draw_strain(node_list,connect_node,Uw,mode,s)
        else:
            print("输入错误")

utils.py主要存储main.py中的一些方法

from node import *
import numpy
import matplotlib.pyplot as plt
from node import *
def convert(list1):
    for i in range(len(list1)):
        list2=list1[i]
        for j in range(len(list2)):
            k = list1[i][j]
            list1[i][j]=float(k)
    return  list1
def convert1(list1):
    for i in range(len(list1)):
        list2=list1[i]
        for j in range(len(list2)):
            k = list1[i][j]
            list1[i][j]=int(k)
    return  list1
def add_node_utils(node_list):
    I=0
    print('结束输入:end')
    while True:
        x = input("请输入节点的x y z坐标,或者退出:")
        #print(node_list)
        if x=="end":
            break
        if len(x.split(" "))!=3:
            print("输入错误")
            raise ValueError
        if x.split(' ') in node_list:
            print("节点已存在")
            raise ValueError
        node_list=add_node(node_list,x.split(" "))
        print("节点添加成功")
        print('node_list')
        for i in range(len(node_list)):
            print(i)
            print(node_list[i])

    return node_list

def remove_node_utils(node_list):
    I=0
    print('结束输入输入:end')
    while True:
        x = input("请输入节点的index:")
        print('node_list')
        for i in range(len(node_list)):
            print(i)
            print(node_list[i])
        node_list.pop(int(x))
        print('node_list')
        for i in range(len(node_list)):
            print(i)
            print(node_list[i])
        if x.pop()=="end":
            break
    return node_list

def add_connect_utils(node_list,connect_list):
    I=0
    print('结束输入:end')
    while True:
        #print('没有此力请输入0')
        x = input("请输入节点的index index:")
        if x=="end":
            break
        if int(x.split(' ')[0])>len(node_list) or int(x.split(' ')[1])>len(node_list):
            print("节点不存在")
            raise ValueError
        print('node_list')
        for i in range(len(node_list)):
            print(i)
            print(node_list[i])
        connect_list=connect_node(connect_list,x.split(" "))
        print('connect_list')
        for i in range(len(connect_list)):
            print(i)
            print(connect_list[i])

    return connect_list

def add_point_utils(node_list,connect_list,dist_list):
    I=0
    print('结束输入:end')
    while True:
        x = input("请输入节点的连接序号 起始点距离占比:")
        if x=="end":
            print('node_list')
            for i in range(len(node_list)):
                print(i)
                print(node_list[i])
            print('connect_list')
            
            for i in range(len(connect_list)):
                print(i)
                print(connect_list[i])
            print('dist_list')
            for i in range(len(dist_list)):
                print(i)
                print(dist_list[i])
            break
        
        if int(x.split(' ')[0])>len(connect_list):
            print("连接不存在")
            raise ValueError
        print('node_list')
        for i in range(len(node_list)):
            print(i)
            print(node_list[i])
        print('connect_list')
        for i in range(len(connect_list)):
            print(i)
            print(connect_list[i])
        print('dist_list')
        dist_list=add_point(dist_list,x.split(" "))

        for i in range(len(dist_list)):
            print(i)
            print(dist_list[i])

    return dist_list

def remove_connect_utils(node_list,connect_list):
    I=0
    print('结束输入:end')
    while True:
        x = input("请输入节点的连接序号:")
        for i in range(len(node_list)):
            print(i)
            print(node_list[i])
        
        for i in range(len(connect_list)):
            print(i)
            print(connect_list[i])
        connect_list.pop(int(x))
        if x=="end":
            for i in range(len(node_list)):
                print(i)
            print(node_list[i])
            
            for i in range(len(connect_list)):
                print(i)
                print(connect_list[i])
            break
    return connect_list

def remove_point_utils(node_list,connect_list,dist_list):
    I=0
    print('结束输入:end')
    while True:
        x = input("index")
        for i in range(len(dist_list)):
            print(i)
            print(dist_list[i])
        
        dist_list.pop(int(x))
        if x=="end":
            for i in range(len(node_list)):
                print(i)
            print(node_list[i])
            
            for i in range(len(connect_list)):
                print(i)
                print(connect_list[i])
            break
    return dist_list
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def plot(node_list,connect_list):
    # 你提供的三维点的列表
    points =node_list
    # 给定两个点在列表中的索引
    connections = []# 两个点的索引连接
    for i in range(len(connect_list)):
        connections.append([int(connect_list[i][0]),int(connect_list[i][1])])
    print(points)
    print(connections)
    # 提取点的坐标
    x = [float(point[0]) for point in points]
    y = [float(point[1]) for point in points]
    z = [float(point[2]) for point in points]

    # 画出点
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(x, y, z, c='r', marker='o')  # 画出红色的点

    # 画出连线
    for connection in connections:
        point1_index, point2_index = connection
        ax.plot([x[point1_index], x[point2_index]],
                [y[point1_index], y[point2_index]],
                [z[point1_index], z[point2_index]], c='b')

    # 设置图表标题和坐标轴标签
    ax.set_title('3D Scatter Plot with Line')
    ax.set_xlabel('X-axis')
    ax.set_ylabel('Y-axis')
    ax.set_zlabel('Z-axis')

    # 显示图表
    plt.show()



def add_force(R,node_list,connect_list,mode):
#输入外载荷,单元内的外力平均分配到两结点,

    print('载荷施加在结点上,用列表表示其性质:[作用结点号,类型(力为0,力矩为1),x方向分量,y方向分量,z方向分量]\n节点编号与结构图如下')
    plot(node_list,connect_list)
    force_input = input('请输入\n作用结点号,类型(力为0,力矩为1,杆只能输入力),x方向分量,y方向分量,z方向分量\n输入完毕请输入0结束此步骤\n').split(',')
    force_input = list(map(float,force_input))
    while True:
        if force_input == [0]:
            print('以下是在载荷')
            for i in range(0,len(R)):
                F = R[i]
                print('结点'+str(F[0]),'类型'+str(F[1]),'x方向分量'+str(F[2]),'y方向分量'+str(F[3]),'z方向分量'+str(F[4]))
            break
        else:
            if len(force_input) != 5:
                print('参数不全!!!!!')
                force_input = input('请输入\n作用结点号,类型(力为0,力矩为1),x方向分量,y方向分量,z方向分量\n输入完毕请输入0结束此步骤\n').split(',')
                force_input = list(map(float,force_input))
            elif mode == 0 and force_input[1] != 0:
                print('桁架模式下只能输入力!!!!!')
                force_input = input('请输入\n作用结点号,类型(力为0,力矩为1),x方向分量,y方向分量,z方向分量\n输入完毕请输入0结束此步骤\n').split(',')
                force_input = list(map(float,force_input))
            else:
                R.append(force_input)
                print('输入成功,请输入下一载荷')
                force_input = input('请输入\n作用结点号,类型(力为0,力矩为1),x方向分量,y方向分量,z方向分量\n输入完毕请输入0结束此步骤\n').split(',')
                force_input = list(map(float,force_input))
    return R
#单元矩阵计算
def cal_lam(ary,mode,ex_node = 0):
    ele_x = ary/np.linalg.norm(ary)
    if mode == 0:
        #---------------------------------------------------------------------------------------------------------------------
        lam = np.matrix([[ele_x[0],ele_x[1],ele_x[2],0,0,0],[0,0,0,ele_x[0],ele_x[1],ele_x[2]]],dtype=float)
        #---------------------------------------------------------------------------------------------------------------------
        return lam
    elif mode == 1:
        lx,mx,nx = (ele_x[0],ele_x[1],ele_x[2])
        enx = ex_node/np.linalg.norm(ex_node)
        p1,p2,p3 = (enx[0],enx[1],enx[2])
        s = np.sqrt((mx*p3-nx*p2)**2+(nx*p1-lx*p3)**2+(lx*p2-mx*p1)**2)
        lmn = lx*p1+mx*p2+nx*p3
        ly,my,ny,lz,mz,nz = ((p1-lx*lmn)/s,(p2-mx*lmn)/s,(p3-nx*lmn)/s,(mx*p3-nx*p2)/s,(nx*p1-lx*p3)/s,(lx*p2-mx*p1)/s)
        lam = np.matrix([[lx,ly,lz],[mx,my,mz],[nx,ny,nz]])
        return lam

def cal_k_or_m(m,Node,Rod,Lam,Ke,Me):
    kw = np.matrix(np.zeros((3*(m+1)*len(Node),3*(m+1)*len(Node)),dtype=float))
    mw = np.matrix(np.zeros((3*(m+1)*len(Node),3*(m+1)*len(Node)),dtype=float))
    t0 = np.matrix(np.zeros((3,3),dtype=float))
    for i in range(len(Rod)):
        start_num = Rod[i][0]
        end_num = Rod[i][1]
        if m==0:
            te = Lam[i].T
        elif m==1:
            te = np.vstack((np.hstack((Lam[i],t0,t0,t0)),np.hstack((t0,Lam[i],t0,t0)),np.hstack((t0,t0,Lam[i],t0)),np.hstack((t0,t0,t0,Lam[i]))))
        ke = np.dot(np.dot(te,Ke[i]),te.T)
        me = np.dot(np.dot(te,Me[i]),te.T)
        start1,start2,end1,end2 = (int(3*(m+1)*start_num),int(3*(m+1)*(start_num+1)),int(3*(m+1)*end_num),int(3*(m+1)*(end_num+1)))
        n1,n2 = (int(3*(m+1)),int(6*(m+1)))
        kw[start1:start2,start1:start2] += ke[0:n1,0:n1]
        kw[start1:start2,end1:end2] += ke[0:n1,n1:n2]
        kw[end1:end2,start1:start2] += ke[n1:n2,0:n1]
        kw[end1:end2,end1:end2] += ke[n1:n2,n1:n2]
        mw[start1:start2,start1:start2] += me[0:n1,0:n1]
        mw[start1:start2,end1:end2] += me[0:n1,n1:n2]
        mw[end1:end2,start1:start2] += me[n1:n2,0:n1]
        mw[end1:end2,end1:end2] += me[n1:n2,n1:n2]
    return [kw,mw]
def u_and_fw(m,Node,R,Rod,Lam,Ke,Me):
    u = np.zeros(((m+1)*3*len(Node),1),dtype=float)
    fw = np.zeros(((m+1)*3*len(Node),1),dtype=float)
    for i in range(0,len(R)):
        force_inf = R[i]
        for j in range(0,3):
            fw[(int(3*force_inf[0]+3*force_inf[1]+j),0)] += force_inf[j+2]
    return [u,fw]
def cal(Fw,Kw,mode,Node,Us):
    #处理约束
    #Us = [[0,0,0],[0,1,0],[1,0,0],[1,1,0]]#输入约束,元素为列表,每个代表一项约束,其中第一项为结点号,第二项为位移分量编号,第三项为位移值
    #处理刚度矩阵与载荷列向量
    for i in range(0,len(Us)):
        us = Us[i]
        Fw[int(3*(mode+1)*us[0]+us[1]),0] = us[2]
        Kw[int(3*(mode+1)*us[0]+us[1]),:] = 0
        Kw[:,int(3*(mode+1)*us[0]+us[1])] = 0
        Kw[int(3*(mode+1)*us[0]+us[1]),int(3*(mode+1)*us[0]+us[1])] = 1

    Z = []
    for i in range(len(Node)):
        Z.append(float(Node[i][-1]))
    if Z==[0.0]*len(Node):
        for i in range(len(Node)):
            Fw[int(3*(mode+1)*i+2),0] = 0
            Kw[int(3*(mode+1)*i+2),:] = 0
            Kw[:,int(3*(mode+1)*i+2)] = 0
            Kw[int(3*(mode+1)*i+2),int(3*(mode+1)*i+2)] = 1
            if mode==1:
                Fw[int(3*(mode+1)*i+4),0] = 0
                Kw[int(3*(mode+1)*i+4),:] = 0
                Kw[:,int(3*(mode+1)*i+4)] = 0
                Kw[int(3*(mode+1)*i+4),int(3*(mode+1)*i+4)] = 1
                Fw[int(3*(mode+1)*i+5),0] = 0
                Kw[int(3*(mode+1)*i+5),:] = 0
                Kw[:,int(3*(mode+1)*i+5)] = 0
                Kw[int(3*(mode+1)*i+5),int(3*(mode+1)*i+5)] = 1
    return np.dot(Kw.I,Fw)

# Drawing strains with scaling
def draw_strain(dic, rod, U,mode, scale_factor=1000):
    fig = plt.figure()
    ax = fig.add_subplot(projection="3d")

    # Original structure
    for i in range(len(rod)):
        rod_node = rod[i]
        node_coord1 = dic[rod_node[0]]
        node_coord2 = dic[rod_node[1]]
        x, y, z = [node_coord1[0], node_coord2[0]], [node_coord1[1], node_coord2[1]], [node_coord1[2], node_coord2[2]]
        ax.scatter(x, y, z, c='red', s=10)
        ax.plot(x, y, z, color='black')

    # Deformed structure with scaling
    for i in range(len(rod)):
        rod_node = rod[i]
        node_coord1 = dic[rod_node[0]]
        node_coord2 = dic[rod_node[1]]
        x = [node_coord1[0] + scale_factor * U[int(3 * (mode + 1) * rod_node[0])], 
             node_coord2[0] + scale_factor * U[int(3 * (mode + 1) * rod_node[1])]]
        y = [node_coord1[1] + scale_factor * U[int(3 * (mode + 1) * rod_node[0] + 1)], 
             node_coord2[1] + scale_factor * U[int(3 * (mode + 1) * rod_node[1] + 1)]]
        z = [node_coord1[2] + scale_factor * U[int(3 * (mode + 1) * rod_node[0] + 2)], 
             node_coord2[2] + scale_factor * U[int(3 * (mode + 1) * rod_node[1] + 2)]]

        # Flatten the arrays before passing to scatter and plot functions
        x, y, z = np.array(x).flatten(), np.array(y).flatten(), np.array(z).flatten()

        ax.scatter(x, y, z, c='blue', s=10)
        ax.plot(x, y, z, color='black')

    plt.show()
def get_l(l):
    print('输入约束,元素为列表,每个代表一项约束,其中第一项为结点号,第二项为位移分量编号,第三项为位移值')
    while True:
        x = input('请输入约束,输入0结束此步骤\n').split(',')
        print(x)
        if x == ['0']:
            break
        else:
            l.append(x)
    return l

下面是node.py主要用于单元和节点的添加:

import numpy as np
import math
'''同学们,下面是计算固体力学编程作业:
编写求解三维桁架或三维刚架静位移、应力以及固有模态的程序。程序语言不限,用A4纸正反面打印,12月14号交。
程序模块包括:
1结点,单元,材料性质和外载荷输入模块;
2 单元矩阵计算和组装模块;
3 考虑位移边界条件,求解静力问题,并画出结构变形图模块;
4 考虑位移边界条件,求解广义本征值方程,并画出前5阶模态图模块。@所有人 '''
# 1结点,单元,材料性质和外载荷输入模块;
def add_node(node_list, list):#添加一个节点
    node_list.append(list)
    return node_list

def connect_node(connect_node ,list):#连接两个节点,返回两个节点的坐标和材料性质
    connect_node.append(list)
    return connect_node

def add_point(dist_list,list):#添加一个节点间的节点
    dist_list.append(list)
    return dist_list

下面是calculate.py(已废弃):

import numpy as np
import numpy.linalg as la
import math
'''
numpy.linalg.det(a): 计算矩阵的行列式。
numpy.linalg.inv(a): 计算矩阵的逆矩阵。
numpy.linalg.eig(a): 计算方阵的特征值和特征向量。
numpy.linalg.solve(a, b): 解线性方程组 Ax = b,其中 A 是系数矩阵,b 是右侧的常数向量。
numpy.linalg.norm(x, ord=None): 计算向量或矩阵的范数。
numpy.linalg.svd(a, full_matrices=True): 计算奇异值分解。
'''
def get_dist(node_list,idx1,idx2):
    return la.norm(np.array(node_list[idx1])-np.array(node_list[idx2]))
#def get_angle(node_list,idx1,idx2):
def get_angle_x(node_list,idx1,idx2):
    vector = np.array(node_list[idx1])-np.array(node_list[idx2])
    # 计算向量的模
    magnitude = np.linalg.norm(vector)
    # 计算角(弧度)
    angle_rad = np.arccos(vector[0] / magnitude)
    # 将弧度转换为度
    return angle_rad
def get_angle_y(node_list,idx1,idx2):
    vector = np.array(node_list[idx1])-np.array(node_list[idx2])
    # 计算向量的模
    magnitude = np.linalg.norm(vector)
    # 计算夹角(弧度)
    angle_rad = np.arccos(vector[1] / magnitude)
    # 将弧度转换为度
    return angle_rad
def get_angle_z(node_list,idx1,idx2):
    vector = np.array(node_list[idx1])-np.array(node_list[idx2])
    # 计算向量的模
    magnitude = np.linalg.norm(vector)
    # 计算夹角(弧度)
    angle_rad = np.arccos(vector[2] / magnitude)
    # 将弧度转换为度
    return angle_rad

About

计算固体力学结构力学求解器(三维桁架求解器:衔架位移&衔架固有频率)Computational Soild Mechanics Class homework

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages