首页/文章/ 详情

面向对象有限元编程|单元类

6月前浏览5701

单元对象是构成整个结构对象的基本要素,如杆单元,梁单元,板单元,壳单元等等。虽然单元形状和特性各不相同,但基本特征和功能是相同的。比如都具有一定的几何形状,通过节点与其它单元连接,包含材料信息,在结构分析中各单元皆以单元刚度矩阵的形式组装成整体结构。各种单元的层次关系如图所示

▲单元层次关系

# 抽象单元类(基类)
class AbstractElement:
    def __init__ (self, id):
        self.id = id

对于一个桁架单元,其特征有编号、材料类型、横截面面积、两个节点的信息、单元长度、单元局部坐标与总体坐标的夹角、单元局部坐标与总体坐标的转换矩阵、单元局部坐标系下的刚度矩阵、单元整体坐标系下的刚度矩阵、应力矩阵、应变矩阵等等。

# 平面桁架单元类
class TrussElement2D(AbstractElement):
    def __init__ (self,id, A, mat, node1, node2):
        super().__init__(id)
        self.A = A
        self.mat = mat
        self.node1 = node1
        self.node2 = node2

    def elemDisp(self):
        return np.array( [ [0.], [0.], [0.], [0.] ] )
                          


    def elemLength(self):
        dx = self.node2.coord_X - self.node1.coord_X
        dy = self.node2.coord_Y - self.node1.coord_Y
        return  math.sqrt(dx*dx + dy*dy)

    def COS(self):
        dx = self.node2.coord_X - self.node1.coord_X
        return dx / self.elemLength()

    def SIN(self):
        dy = self.node2.coord_Y - self.node1.coord_Y
        return  dy / self.elemLength()

    def Trans(self):
        S = self.SIN()
        C = self.COS()
        return np.array([ [C, S, 00],
                          [00, C, S] ])

    def elemStiffnessMatrix(self):
        EA = self.mat.E * self.A
        S = self.SIN()
        C = self.COS()
        ek = np.array([ [C*C,  C*S, -C*C, -C*S ], 
                       [C*S,  S*S, -C*S, -S*S ], 
                       [-C*C, -C*S, C*C,  C*S], 
                       [-C*S, -S*S, C*S,  S*S]   ] )

        return EA/self.elemLength() * ek

    def strainMatrix(self):
        L  = self.elemLength()
        tmp1 = np.array( [-1.01.0] )
        return 1/L * np.array( [-1.01.0] )
        
    def normalForce(self, T, elemDisp):
        EA = self.mat.E * self.A
        b = self.strainMatrix() 
        tmp1 = EA * b
        
        tmp2 = np.dot(tmp1, T)
        return np.dot(tmp2, elemDisp)

采用从基类按层次继承来建立单元类的方法,除了重用父类代码之外,另一个很重要的优点就是可以运用多态。通过指向单元基类对象的指针,调用各派生单元类的成员函数。来看一个例子:从一个抽象单元类派生个不同的单元类。现在要获取这两个单元的编号。

#include <iostream>
#include <vector>
using namespace std;

class AbstractElement
{

public:

    virtual ~AbstractElement() = default;
    virtual size_t getID() const 0;   // 纯虚函数 
};


class Truss : public AbstractElement
{
protected:
    size_t id{ 0 };

public:
    Truss() = default;
    Truss(size_t id_) : id{ id_ } {}
    size_t getID() const override { return id; }


};


class Beam : public AbstractElement
{
protected:
    size_t id{ 0 };

public:
    Beam() = default;
    Beam(size_t id_) : id{ id_ } {}
    size_t getID() const override { return id; }
};

int main()
{
    Truss t1{ 1 };
    Beam  b1{ 2 };

    std::vector<AbstractElement*> elems{ &t1, &b1 };

    for (auto* el : elems)
    {
        std::cout << el->getID() << std::endl;  //这里体现了多态
    }

 
    return 0;

}


来源:数值分析与有限元编程
ACT材料
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2024-04-02
最近编辑:6月前
太白金星
本科 慢慢来
获赞 5粉丝 8文章 318课程 0
点赞
收藏
作者推荐

面向对象有限元编程|抽象

抽象(Abstraction)指的是“在事物的诸多特征中,保留解决问题所需的部分特征”这一过程。在面向对象编程中,创建类时就要对客观事物进行合理的抽象。假如对一台手机进行抽象,即创建一个手机类。手机的特征很复杂,如品牌、外观颜色、重量、屏幕尺寸、屏幕分辨率、电池电量、内存、SIM卡类型、网络模式、操作系统、CPU型号、上市日期等等。解决的问题不同,手机类的属性和方法也就不同。如果分析手机的耗电量,那么只需要屏幕尺寸、屏幕分辨率、电池电量以及CPU型号这些与问题相关的特征。而忽略其他特征,这就是进行抽象。class SmartPhone: def __init__(self, screenSize, resolution, power, CPUtype): self.screenSize = screenSize #屏幕尺寸 self.resolution = resolution #屏幕分辨率 self.power = power #电池容量mAh self.CPUtype = CPUtype # CPU类型#创建jPhone12手机jPhone12 = SmartPhone(5.45, &quot;1080p&quot;, 2900, &quot;Exynos 9820&quot;) 仅仅是抽象还不够,得以保留的特征是属性还是方法?其实这并没有明确的界限。类的属性是存储数据的,方法就是函数,是操作数据的。如果考虑到内存的占用,可以写成方法,每次需要的时候调用 ,调用完可以释放。如果不考虑内存,可以保存为属性,这样可以全局调用。对于一个桁架单元,其特征有编号、材料类型、横截面面积、两个节点的信息、单元长度、单元局部坐标与总体坐标的夹角、单元局部坐标与总体坐标的转换矩阵、单元局部坐标系下的刚度矩阵、单元整体坐标系下的刚度矩阵、应力矩阵、应变矩阵等等。平板电脑和手机之间有相同点,也有不同点。在对平板电脑进行抽象时,可以借鉴对手机进行抽象的思路。同样,对于梁单元以及其它单元,也可以借鉴对桁架单元进行抽象的思路,做到触类旁通。来源:数值分析与有限元编程

未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈