C++实现有限元三维杆单元计算 Bar3D2Node类(纯自研 非套壳)
目录
1、Bar3D2Node类
1.1、public function
1.1.1、构造函数析构函数
1.1.2、设置数值接口函数
1.1.3、获取数值接口函数
1.1.4、计算函数
1.2、private variable
1.3、全部源码
本系列文章致力于实现“手搓有限元,干翻Ansys的目标”,基本框架为前端显示使用QT实现交互,后端计算采用Visual Studio C++。
1、Bar3D2Node类
Bar3D2Node类用来实现有限元中三维杆单元的计算。继承了二维杆单元(Bar2D2Node,点击此处跳转Bar2D2Node的介绍),整体架构如下:
1.1、public function
1.1.1、构造函数析构函数
有参构造函数用来初始化单元的ID、起始节点、结束节点、杨氏模量、横截面积;析构函数用来释放内存。
Bar3D2Node.h函数声明:
//***********************构造函数析构函数***********************//
Bar3D2Node();
/*
函数名称: 有参构造函数
id: 单元ID
p0: 3D节点1
p1: 3D节点2
E: 单元杨氏模量
A: 单元横截面积
*/
Bar3D2Node(int id, Point3D* p0, Point3D* p1, double E, double A);
~Bar3D2Node();
Bar3D2Node.cpp函数实现:
Bar3D2Node::Bar3D2Node()
{
}
//有参构造函数
Bar3D2Node::Bar3D2Node(int id, Point3D* p0, Point3D* p1, double E, double A)
{
//通过继承的函数设置属性
this->SetID(id);
//3DPoint赋值
this->m_Point0 = p0;
this->m_Point1 = p1;
//通过继承的函数设置属性
this->SetE(E);
this->SetA(A);
}
Bar3D2Node::~Bar3D2Node()
{
}
1.1.2、设置数值接口函数
设置数值接口函数可以设置单元的ID、起始节点、结束节点、杨氏模量、横截面积。
Bar3D2Node.h函数声明:
//***********************设置数值接口函数***********************//
/*
函数名称: 设置杆单元系数
id: 单元ID
*p0: Bar3D2Node单元起始点
*p1: Bar3D2Node单元终止点
E: 单元杨氏模量
A: 单元横截面积
*/
virtual void SetBar(int id, Point3D* p0, Point3D* p1, double E, double A);
/*
函数名称: 设置单元组成点
*p0: Bar3D2Node单元起始点
*p1: Bar3D2Node单元终止点
*/
virtual void SetPoint(Point3D* p0, Point3D* p1);
Bar3D2Node.cpp函数实现:
//设置杆单元系数
void Bar3D2Node::SetBar(int id, Point3D* p0, Point3D* p1, double E, double A)
{
//通过继承的函数设置属性
this->SetID(id);
//3DPoint赋值
this->m_Point0 = p0;
this->m_Point1 = p1;
//通过继承的函数设置属性
this->SetE(E);
this->SetA(A);
}
//设置单元组成点
void Bar3D2Node::SetPoint(Point3D* p0, Point3D* p1)
{
//3DPoint赋值
this->m_Point0 = p0;
this->m_Point1 = p1;
}
1.1.3、获取数值接口函数
可以获取三维杆单元的起始节点、终止节点。
Bar3D2Node.h函数声明:
//***********************获取数值接口函数***********************//
/*
函数名称: 获取bar3D2Node单元起始点
*/
Point3D* GetPoint0();
/*
函数名称: 获取bar3D2Node单元终止点
*/
Point3D* GetPoint1();
Bar3D2Node.cpp函数实现:
//获取bar3D2Node单元起始点
Point3D* Bar3D2Node::GetPoint0()
{
return this->m_Point0;
}
//获取bar3D2Node单元终止点
Point3D* Bar3D2Node::GetPoint1()
{
return this->m_Point1;
}
1.1.4、计算函数
这些函数可以计算刚度矩阵、单元应变和单元应力。
Bar3D2Node.h函数声明:
//***************************计算函数***************************//
/*
函数名称: 创建刚度矩阵(全局)
*/
virtual Matrix CreateK();
/*
函数名称: 计算单元应变
*/
virtual double CalEpsilon();
/*
函数名称: 计算杆单元应力
*/
virtual double CalSigama();
Bar3D2Node.cpp函数实现:
//创建刚度矩阵(全局)
Matrix Bar3D2Node::CreateK()
{
//计算投影数值
double deletaX = this->m_Point1->GetX() - this->m_Point0->GetX();
double deletaY = this->m_Point1->GetY() - this->m_Point0->GetY();
double deletaZ = this->m_Point1->GetZ() - this->m_Point0->GetZ();
//计算杆件长度
double barLength = sqrt(pow(deletaX, 2) + pow(deletaY, 2) + pow(deletaZ, 2));
//计算方向余弦
double cosX = deletaX / barLength;
double cosY = deletaY / barLength;
double cosZ = deletaZ / barLength;
//构造旋转矩阵
double T[12] = {cosX, cosY, cosZ, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, cosX, cosY, cosZ};
Matrix MatT(2, 6, T);
//局部刚度矩阵
double k[4] = { 1.0, -1.0, -1.0, 1.0 };
Matrix Matk(2, 2, k);
//刚度矩阵系数
double var1 = this->GetE() * this->GetA() / barLength;
Matk = Matk.MultNum(var1);
//全局刚度矩阵
this->m_MatK = MatT.Transpose().MultMat(Matk).MultMat(MatT);
//矩阵打印
this->m_MatK.PrintMat();
return this->m_MatK;
}
//计算单元应变
double Bar3D2Node::CalEpsilon()
{
//计算投影数值
double deletaX = this->m_Point1->GetX() - this->m_Point0->GetX();
double deletaY = this->m_Point1->GetY() - this->m_Point0->GetY();
double deletaZ = this->m_Point1->GetZ() - this->m_Point0->GetZ();
//计算杆件长度
double barLength = sqrt(pow(deletaX, 2) + pow(deletaY, 2) + pow(deletaZ, 2));
//计算方向余弦
double cosX = deletaX / barLength;
double cosY = deletaY / barLength;
double cosZ = deletaZ / barLength;
//构造旋转矩阵
double T[12] = { cosX, cosY, cosZ, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, cosX, cosY, cosZ };
Matrix MatT(2, 6, T);
//构建B矩阵
double B[2] = { -1 / barLength, 1 / barLength };
Matrix MatB(1, 2, B);
//构建位移矩阵
double q[6] = { this->m_Point0->GetU(), this->m_Point0->GetV(), this->m_Point0->GetW(),
this->m_Point1->GetU(), this->m_Point1->GetV(), this->m_Point1->GetW() };
Matrix Matq(6, 1, q);
//计算sigama
this->m_Epsilon = MatB.MultMat(MatT).MultMat(Matq).GetMatrixEle(0, 0);
return this->m_Epsilon;
}
//计算杆单元应力
double Bar3D2Node::CalSigama()
{
//根据本构方程 计算sigama
this->m_Sigama = this->GetEpsilon() * this->GetE();
return this->m_Sigama;
}
1.2、private variable
私有成员变量包括起始节点和结束节点。
Point3D* m_Point0; //杆单元节点1号,存在顺序关系
Point3D* m_Point1; //杆单元节点2号,存在顺序关系
1.3、全部源码
Bar3D2Node.h函数声明:
#ifndef BAR_3D_2NODE_H
#define BAR_3D_2NODE_H
#include "Bar2D2Node.h"
class Bar3D2Node :public Bar2D2Node
{
public:
//***********************构造函数析构函数***********************//
Bar3D2Node();
/*
函数名称: 有参构造函数
id: 单元ID
p0: 3D节点1
p1: 3D节点2
E: 单元杨氏模量
A: 单元横截面积
*/
Bar3D2Node(int id, Point3D* p0, Point3D* p1, double E, double A);
~Bar3D2Node();
//***********************设置数值接口函数***********************//
/*
函数名称: 设置杆单元系数
id: 单元ID
*p0: Bar3D2Node单元起始点
*p1: Bar3D2Node单元终止点
E: 单元杨氏模量
A: 单元横截面积
*/
virtual void SetBar(int id, Point3D* p0, Point3D* p1, double E, double A);
/*
函数名称: 设置单元组成点
*p0: Bar3D2Node单元起始点
*p1: Bar3D2Node单元终止点
*/
virtual void SetPoint(Point3D* p0, Point3D* p1);
//***********************获取数值接口函数***********************//
/*
函数名称: 获取bar3D2Node单元起始点
*/
Point3D* GetPoint0();
/*
函数名称: 获取bar3D2Node单元终止点
*/
Point3D* GetPoint1();
//***************************计算函数***************************//
/*
函数名称: 创建刚度矩阵(全局)
*/
virtual Matrix CreateK();
/*
函数名称: 计算单元应变
*/
virtual double CalEpsilon();
/*
函数名称: 计算杆单元应力
*/
virtual double CalSigama();
private:
Point3D* m_Point0; //杆单元节点1号,存在顺序关系
Point3D* m_Point1; //杆单元节点2号,存在顺序关系
};
#endif
Bar3D2Node.cpp函数实现:
#include "Bar3D2Node.h"
Bar3D2Node::Bar3D2Node()
{
}
//有参构造函数
Bar3D2Node::Bar3D2Node(int id, Point3D* p0, Point3D* p1, double E, double A)
{
//通过继承的函数设置属性
this->SetID(id);
//3DPoint赋值
this->m_Point0 = p0;
this->m_Point1 = p1;
//通过继承的函数设置属性
this->SetE(E);
this->SetA(A);
}
Bar3D2Node::~Bar3D2Node()
{
}
//设置杆单元系数
void Bar3D2Node::SetBar(int id, Point3D* p0, Point3D* p1, double E, double A)
{
//通过继承的函数设置属性
this->SetID(id);
//3DPoint赋值
this->m_Point0 = p0;
this->m_Point1 = p1;
//通过继承的函数设置属性
this->SetE(E);
this->SetA(A);
}
//设置单元组成点
void Bar3D2Node::SetPoint(Point3D* p0, Point3D* p1)
{
//3DPoint赋值
this->m_Point0 = p0;
this->m_Point1 = p1;
}
//获取bar3D2Node单元起始点
Point3D* Bar3D2Node::GetPoint0()
{
return this->m_Point0;
}
//获取bar3D2Node单元终止点
Point3D* Bar3D2Node::GetPoint1()
{
return this->m_Point1;
}
//创建刚度矩阵(全局)
Matrix Bar3D2Node::CreateK()
{
//计算投影数值
double deletaX = this->m_Point1->GetX() - this->m_Point0->GetX();
double deletaY = this->m_Point1->GetY() - this->m_Point0->GetY();
double deletaZ = this->m_Point1->GetZ() - this->m_Point0->GetZ();
//计算杆件长度
double barLength = sqrt(pow(deletaX, 2) + pow(deletaY, 2) + pow(deletaZ, 2));
//计算方向余弦
double cosX = deletaX / barLength;
double cosY = deletaY / barLength;
double cosZ = deletaZ / barLength;
//构造旋转矩阵
double T[12] = {cosX, cosY, cosZ, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, cosX, cosY, cosZ};
Matrix MatT(2, 6, T);
//局部刚度矩阵
double k[4] = { 1.0, -1.0, -1.0, 1.0 };
Matrix Matk(2, 2, k);
//刚度矩阵系数
double var1 = this->GetE() * this->GetA() / barLength;
Matk = Matk.MultNum(var1);
//全局刚度矩阵
this->m_MatK = MatT.Transpose().MultMat(Matk).MultMat(MatT);
//矩阵打印
this->m_MatK.PrintMat();
return this->m_MatK;
}
//计算单元应变
double Bar3D2Node::CalEpsilon()
{
//计算投影数值
double deletaX = this->m_Point1->GetX() - this->m_Point0->GetX();
double deletaY = this->m_Point1->GetY() - this->m_Point0->GetY();
double deletaZ = this->m_Point1->GetZ() - this->m_Point0->GetZ();
//计算杆件长度
double barLength = sqrt(pow(deletaX, 2) + pow(deletaY, 2) + pow(deletaZ, 2));
//计算方向余弦
double cosX = deletaX / barLength;
double cosY = deletaY / barLength;
double cosZ = deletaZ / barLength;
//构造旋转矩阵
double T[12] = { cosX, cosY, cosZ, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, cosX, cosY, cosZ };
Matrix MatT(2, 6, T);
//构建B矩阵
double B[2] = { -1 / barLength, 1 / barLength };
Matrix MatB(1, 2, B);
//构建位移矩阵
double q[6] = { this->m_Point0->GetU(), this->m_Point0->GetV(), this->m_Point0->GetW(),
this->m_Point1->GetU(), this->m_Point1->GetV(), this->m_Point1->GetW() };
Matrix Matq(6, 1, q);
//计算sigama
this->m_Epsilon = MatB.MultMat(MatT).MultMat(Matq).GetMatrixEle(0, 0);
return this->m_Epsilon;
}
//计算杆单元应力
double Bar3D2Node::CalSigama()
{
//根据本构方程 计算sigama
this->m_Sigama = this->GetEpsilon() * this->GetE();
return this->m_Sigama;
}