荷载-位移曲线相关
讲一个很少或几乎没有书去讲的一个问题,就是关于如何解读荷载-位移曲线的。判断平衡状态是否稳定可通过应用Ляпунов(李雅普诺夫)一次近似理论[1],即对于方程通过特征值实部正负来加以判断: (1)如果其特征方程所有特征根均具负实部,则进行轻微扰动后,将依旧回到原平衡位置; (2)如果特征方程至少具有一个正实部的根,则进行轻微扰动后,将无法回复到原平衡位置。……
本例主要基于闭合截面的例子讲如何合理应用python中的继承。 对于由闭合多段线形成的截面,其基类可写为 class 多段线: # 对于一个多端线而言,初始化需要得到节点坐标……
本例主要基于闭合截面的例子讲如何合理应用python中的继承。
对于由闭合多段线形成的截面,其基类可写为
class 多段线:
# 对于一个多端线而言,初始化需要得到节点坐标
def __init__(self):
self.__coords = self.get_coords()
# 求解节点坐标
def get_coords(self):
pass
@property
def Coords(self):
return self.__coords
需要初始化什么,就在__init__
函数中进行添加。对于多段线而言,通过节点坐标来表征,采用求节点坐标函数get_coords()
进行初始化。不过由于具体截面形式未知,故get_coords()
函数略过,需要在子类中进行编写。
对于节点坐标而言,我们不希望其只读,故采用私有属性方式并通过特性实现(并不妨碍子类中继承)。
除了正常的多段线节点坐标,一般而言还需要得到用于高斯积分运算的坐标。当然并不是直接给出高斯积分点,而是矩形截面(对于二维图形)的中心点坐标、长、宽。
# 建立一个多段线类
class 多段线:
# 对于一个多端线而言,初始化
def __init__(self):
self.__coords = self.get_coords()
self.__gauss_coords = self.get_gauss_coords()
# 求解节点坐标
def get_coords(self):
pass
# 求解高斯节点坐标
def get_gauss_coords(self):
pass
@property
def Coords(self):
return self.__coords
@property
def GaussCoords(self):
return self.__gauss_coords
基于高斯节点,可以得到相关截面属性。对于具体求解代码部分,暂时略过。
# 求解面积
@property
def Area(self):
ret = 0
pass
return ret
# 求解面内惯性矩
@property
def Iy(self):
ret = 0
pass
return ret
对于具体的截面,可以继承上述截面并修改相关函数。
class 矩形截面(多段线):
# 纯钢一字型墙,需要进行处理
# 水平向x轴,竖向y轴
def __init__(self,pc =[0,0],L = 200,W = 200):
# 确定多段线上各节点坐标
self.__pc,self.__L,self.__W = pc,L,W
super().__init__()
# 求解节点坐标
def get_coords(self):
pc_x,pc_y,L,W = self.__pc[0],self.__pc[1],self.__L,self.__W
x = [pc_x-L/2,pc_x-L/2,pc_x+L/2,pc_x+L/2]
y = [pc_y-W/2,pc_y+W/2,pc_y+W/2,pc_y-W/2]
ret = []
for i,obj in enumerate(x):
ret = ret + [x[i],y[i]]
return ret
# 求解高斯节点坐标
def get_gauss_coords(self):
pc_x,pc_y,L,W = self.__pc[0],self.__pc[1],self.__L,self.__W
ret= [[pc_x,pc_y,L,W]]
return ret
这里简单起见,直接采用了运行上述代码得到:上述代码中通过静态属性方法用于引用计算得到的节点坐标。至于节点坐标的格式,这里采用的是列表形式,且x、y坐标间隔分布。
继承的主要目的是应用基类的方法和属性。基于具体的高斯节点坐标形式就可以在基类下编写相关截面特性求解语句。相应多段线类改为:
class 多段线:
# 对于一个多端线而言,初始化
def __init__(self):
self.__coords = self.get_coords()
self.__gauss_coords = self.get_gauss_coords()
# 求解节点坐标
def get_coords(self):
pass
# 求解高斯节点坐标
def get_gauss_coords(self):
pass
@property
def Coords(self):
return self.__coords
@property
def GaussCoords(self):
return self.__gauss_coords
# 求解面积
@property
def Area(self):
ret = 0
for i in range(len(self.GaussCoords)):
xc,yc,w,h = self.GaussCoords[i]
f =w/2*h/2*np.ones((3,3))
ret = ret + gs.Gauss9f(f)
return ret
# 求解面内惯性矩
@property
def Iy(self):
ret = 0
for i in range(len(self.GaussCoords)):
xc,yc,w,h = self.GaussCoords[i]
f =(gs.Guass9_X*w/2+xc)*(gs.Guass9_X*w/2+xc)*w/2*h/2
ret = ret + Gauss9f(f)
return ret
# 求解面外惯性矩
@property
def Ix(self):
ret = 0
for i in range(len(self.GaussCoords)):
xc,yc,w,h = self.GaussCoords[i]
f =(gs.Guass9_Y*h/2+yc)*(gs.Guass9_Y*h/2+yc)*w/2*h/2
ret = ret + gs.Gauss9f(f)
return ret
# 求解形心
@property
def 形心(self):
pcx = 0
pcy = 0
for i in range(len(self.GaussCoords)):
xc,yc,w,h = self.GaussCoords[i]
fx = (gs.Guass9_X*w/2+xc)*w/2*h/2
fy = (gs.Guass9_Y*h/2+yc)*w/2*h/2
pcx = pcx + gs.Gauss9f(fx)/self.Area
pcy = pcy + gs.Gauss9f(fy)/self.Area
ret = [pcx,pcy]
return ret
(注:应用上述方法需要引入自编高斯积分模块和numpy)
矩形截面通过继承相应具有了方法和属性:
方法 | 用途 | 属性 | 用途 |
---|---|---|---|
Area | 面积 | Coords | 得到节点坐标 |
Ix | 面外惯性矩 | GaussCoords | 得到用于高斯积分运算的坐标 |
添加计算主程序:
import 模块_高斯积分 as gs
import numpy as np
if __name__ == '__main__':
rec1 = 矩形截面(L=150,W=300)
print(rec1.Coords)
print(rec1.GaussCoords)
print(rec1.Area)
计算得到:
[-75.0, -150.0, -75.0, 150.0, 75.0, 150.0, 75.0, -150.0]
[[0, 0, 150, 300]]
45000.000000000044
小结
附完整代码:
1)主程序
# kiritanimirei.cn
# 2020年2月28日 星期五 天气阴
# 建立一个多段线类
## 多段线类
class 多段线:
# 对于一个多端线而言,初始化
def __init__(self):
self.__coords = self.get_coords()
self.__gauss_coords = self.get_gauss_coords()
# 求解节点坐标
def get_coords(self):
pass
@property
def Coords(self):
return self.__coords
@property
def GaussCoords(self):
return self.__gauss_coords
# 求解面积
@property
def Area(self):
ret = 0
for i in range(len(self.GaussCoords)):
xc,yc,w,h = self.GaussCoords[i]
f =w/2*h/2*np.ones((3,3))
ret = ret + gs.Gauss9f(f)
return ret
# 求解面内惯性矩
@property
def Iy(self):
ret = 0
for i in range(len(self.GaussCoords)):
xc,yc,w,h = self.GaussCoords[i]
f =(gs.Guass9_X*w/2+xc)*(gs.Guass9_X*w/2+xc)*w/2*h/2
ret = ret + Gauss9f(f)
return ret
# 求解面外惯性矩
@property
def Ix(self):
ret = 0
for i in range(len(self.GaussCoords)):
xc,yc,w,h = self.GaussCoords[i]
f =(gs.Guass9_Y*h/2+yc)*(gs.Guass9_Y*h/2+yc)*w/2*h/2
ret = ret + gs.Gauss9f(f)
return ret
# 求解形心
@property
def 形心(self):
pcx = 0
pcy = 0
for i in range(len(self.GaussCoords)):
xc,yc,w,h = self.GaussCoords[i]
fx = (gs.Guass9_X*w/2+xc)*w/2*h/2
fy = (gs.Guass9_Y*h/2+yc)*w/2*h/2
pcx = pcx + gs.Gauss9f(fx)/self.Area
pcy = pcy + gs.Gauss9f(fy)/self.Area
ret = [pcx,pcy]
return ret
class 矩形截面(多段线):
# 纯钢一字型墙,需要进行处理
# 水平向x轴,竖向y轴
def __init__(self,pc =[0,0],L = 200,W = 200):
# 确定多段线上各节点坐标
self.__pc,self.__L,self.__W = pc,L,W
super().__init__()
# 求解节点坐标
def get_coords(self):
pc_x,pc_y,L,W = self.__pc[0],self.__pc[1],self.__L,self.__W
x = [pc_x-L/2,pc_x-L/2,pc_x+L/2,pc_x+L/2]
y = [pc_y-W/2,pc_y+W/2,pc_y+W/2,pc_y-W/2]
cc = []
for i,obj in enumerate(x):
cc = cc + [x[i],y[i]]
return cc
# 求解高斯节点坐标
def get_gauss_coords(self):
pc_x,pc_y,L,W = self.__pc[0],self.__pc[1],self.__L,self.__W
ret= [[pc_x,pc_y,L,W]]
return ret
import 模块_高斯积分 as gs
import numpy as np
if __name__ == '__main__':
rec1 = 矩形截面(L=150,W=300)
print(rec1.Coords)
print(rec1.GaussCoords)
print(rec1.Area)
2)采用的"模块_高斯积分"模块如下所示:
import numpy as np
dg= 0.774596669241483
Guass9_X = np.array([[-dg,-dg,-dg],[0,dg,dg],[dg,0,0]])
Guass9_Y = np.array([[-dg,0,dg],[dg,dg,0],[-dg,-dg,0]])
we1 = 0.308641975308642
we2 = 0.493827160493828
we3 = 0.790123456790124
weight9 = np.array([[we1,we2,we1],[we2,we1,we2],[we1,we2,we3]])
def Gauss9f(f):
ret = np.sum(weight9*f)
return ret