计算案例:
其中弹性模量设置为1,泊松比设置为0.2
节点坐标:1(3,0)2(1.5,0)3(0,0)4(3,-0.4)5(1.5,-0.4)6(0,-0.4)
等效节点荷载:1(0,-1),其他节点为0
边界条件:节点3,4的位移为0
C语言计算结果窗口:
根据窗口提示输入初始条件,程序可实现任意节点数三角形单元计算,与有限元软件计算结果一致,下附C语言程序代码:
#include <stdio.h>
#include <Windows.h>
#include <math.h>
#include <stdlib.h>
#pragma warning(disable:4996)
void print1(double **arr, int row, int col){ //输出矩阵
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf("%6.2f", arr[i][j]);
}
printf("\n");
} }
double **str (double x[3][2],int t,int E,double u,double*U,int m){
double x1, y1;
x1=x[0][0],y1=x[0][1];
double x2, y2;
x2=x[1][0],y2=x[1][1];
double x3, y3;
x3=x[2][0],y3=x[2][1];
double a1 = x2*y3 - x3*y2;
double a2 = x3*y1 - x1*y3;
double a3 = x1*y2 - x2*y1;
double b1 = y2 - y3;
double b2 = y3 - y1;
double b3 = y1 - y2;
double c1 = x3 - x2;
double c2 = x1 - x3;
double c3 = x2 - x1;
//算出该三角形的边长length1、2、3;
double length1 = sqrt((double)(x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2));
double length2 = sqrt((double)(x2 - x3)*(x2 - x3) + (y2 - y3)*(y2 - y3));
double length3 = sqrt((double)(x1 - x3)*(x1 - x3) + (y1 - y3)*(y1 - y3));
//算出该三角形的周长per
double per = (length1 + length2 + length3) / 2;
//算出该三角形的面积area;
double area = sqrt(per*(per - length1)*(per - length2)*(per - length3));
//建立几何矩阵(用二维数组实现)
double B[3][6];
memset(B, 0.0, sizeof(B));
//二维数组初始化
double cd = 1 / (2 * area);
//根据课本中的3-9公式
//第一行
B[0][0] = b1*cd;
B[0][2] = b2*cd;
B[0][4] = b3*cd;
//第二行
B[1][1] = c1*cd;
B[1][3] = c2*cd;
B[1][5] = c3*cd;
//第三行
B[2][0] = c1*cd;
B[2][1] = b1*cd;
B[2][2] = c2*cd;
B[2][3] = b2*cd;
B[2][4] = c3*cd;
B[2][5] = b3*cd;
//完成几何矩阵的创建;
//由于u=0,平面应力与平面问题的D相同;
//计算应力弹性矩阵
double D[3][3] = { { 1.0, u, 0.0 }, \
{u, 1.0, 0.0}, \
{0.0, 0.0, (1 - u) / 2}
};
for (int i = 0; i < (sizeof(D) / sizeof(D[0])); i++){
D[0][i] *= (E / (1 - u*u));
D[1][i] *= (E / (1 - u*u));
D[2][i] *= (E / (1 - u*u));
}//求得最终的应力弹性矩阵;
//计算应力转换矩阵
double S[3][6];
//数组初始化;
memset(S, 0.0, sizeof(S));
//S=D*B;
for (int j = 0; j < (sizeof(D) / sizeof(D[0])); j++){
for (int i = 0; i < (sizeof(D) / sizeof(D[0])); i++){
S[j][0] += D[j][i] * B[i][0];
S[j][1] += D[j][i] * B[i][1];
S[j][2] += D[j][i] * B[i][2];
S[j][3] += D[j][i] * B[i][3];
S[j][4] += D[j][i] * B[i][4];
S[j][5] += D[j][i] * B[i][5];
}
}
double strain[3];
memset(strain, 0.0, sizeof(strain));
for (int j = 0; j <3; j++){
for (int i = 0; i < 6; i++){
strain[j] +=B[j][i]*U[i];
}
}
double stress[3];
memset(stress, 0.0, sizeof(stress));
for (int j = 0; j <3; j++){
for (int i = 0; i < 6; i++){
stress[j] +=S[j][i]*U[i];
}
}printf("第%d个单元应变:\n",m);
for (int j = 0; j < 3; j++)
printf("%6.2f", strain[j]);
printf("\n");
printf("第%d个单元应力:\n",m);
for (int j = 0; j < 3; j++)
printf("%6.2f", stress[j]);
printf("\n");
return 0;}
double **gd (double x[3][2],int t,int E,double u){
double x1, y1;
x1=x[0][0],y1=x[0][1];
double x2, y2;
x2=x[1][0],y2=x[1][1];
double x3, y3;
x3=x[2][0],y3=x[2][1];
double a1 = x2*y3 - x3*y2;
double a2 = x3*y1 - x1*y3;
double a3 = x1*y2 - x2*y1;
double b1 = y2 - y3;
double b2 = y3 - y1;
double b3 = y1 - y2;
double c1 = x3 - x2;
double c2 = x1 - x3;
double c3 = x2 - x1;
//算出该三角形的边长length1、2、3;
double length1 = sqrt((double)(x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2));
double length2 = sqrt((double)(x2 - x3)*(x2 - x3) + (y2 - y3)*(y2 - y3));
double length3 = sqrt((double)(x1 - x3)*(x1 - x3) + (y1 - y3)*(y1 - y3));
//算出该三角形的半周长per
double per = (length1 + length2 + length3) / 2;
//算出该三角形的面积area;
double area = sqrt(per*(per - length1)*(per - length2)*(per - length3));
//建立几何矩阵(用二维数组实现)
double B[3][6];
memset(B, 0.0, sizeof(B));
//二维数组初始化
double cd = 1 / (2 * area);
//根据课本中的3-9公式
//第一行
B[0][0] = b1*cd;
B[0][2] = b2*cd;
B[0][4] = b3*cd;
//第二行
B[1][1] = c1*cd;
B[1][3] = c2*cd;
B[1][5] = c3*cd;
//第三行
B[2][0] = c1*cd;
B[2][1] = b1*cd;
B[2][2] = c2*cd;
B[2][3] = b2*cd;
B[2][4] = c3*cd;
B[2][5] = b3*cd;
//完成几何矩阵的创建;
//由于u=0,平面应力与平面问题的D相同;
//计算应力弹性矩阵
double D[3][3] = { { 1.0, u, 0.0 }, \
{u, 1.0, 0.0}, \
{0.0, 0.0, (1 - u) / 2}
};
for (int i = 0; i < (sizeof(D) / sizeof(D[0])); i++){
D[0][i] *= (E / (1 - u*u));
D[1][i] *= (E / (1 - u*u));
D[2][i] *= (E / (1 - u*u));
}//求得最终的应力弹性矩阵;
//计算应力转换矩阵
double S[3][6];
//数组初始化;
memset(S, 0.0, sizeof(S));
//S=D*B;
for (int j = 0; j < (sizeof(D) / sizeof(D[0])); j++){
for (int i = 0; i < (sizeof(D) / sizeof(D[0])); i++){
S[j][0] += D[j][i] * B[i][0];
S[j][1] += D[j][i] * B[i][1];
S[j][2] += D[j][i] * B[i][2];
S[j][3] += D[j][i] * B[i][3];
S[j][4] += D[j][i] * B[i][4];
S[j][5] += D[j][i] * B[i][5];
}
}
//将B、S及t,面积area带入公式得单元刚度矩阵Ke;
//求得B的转置矩阵B1;
double B1[6][3];
memset(B1, 0.0, sizeof(B1));
for (int i = 0; i < (sizeof(B1) / sizeof(B1[0])); i++){
B1[i][0] = B[0][i];
B1[i][1] = B[1][i];
B1[i][2] = B[2][i];
}
//求单元刚度矩阵;
double **B1S;
B1S = (double **)malloc(sizeof(double *) * 6);
for (int i = 0; i < 6; i++) {
B1S[i] = (double*)malloc(sizeof(double) *6);
}
for(int i=0;i<6;i++)
for(int j=0;j<6;j++)
B1S[i][j]=0;
for (int j = 0; j < 6; j++){
for (int i = 0; i< 3; i++){
B1S[j][0] += B1[j][i] * S[i][0];
B1S[j][1] += B1[j][i] * S[i][1];
B1S[j][2] += B1[j][i] * S[i][2];
B1S[j][3] += B1[j][i] * S[i][3];
B1S[j][4] += B1[j][i] * S[i][4];
B1S[j][5] += B1[j][i] * S[i][5];
}}
for (int j = 0; j < 6; j++){
for (int i = 0; i < 6; i++){
B1S[i][j] *= (area*t);
}
}
return B1S;
}
int main() {
//输入基本参数
int t=1;
int E;
printf("请输入弹性模量:\n");
scanf_s("%d", &E);
double u ;
printf("请输入泊松比:\n");
scanf_s("%lf", &u);
int i, j, line, column = 2; //line表示节点数
printf("请输入节点数:\n");
scanf_s("%d", &line);
double **x; //定义二位数组的首地址(首地址为二级指针)
x = (double **)malloc(sizeof(double *) * line); //给行指针分配内存空间
for (i = 0; i < line; i++) {
x[i] = (double*)malloc(sizeof(double) * column); //给每个行指针后面分配2个int的空间作为列
}
printf("请依次输入节点的x、y坐标:\n");
for( i=0;i<line;i++)
scanf_s("%lf%lf",&x[i][0],&x[i][1]);
//确定单元节点
int danyuan;
printf("请输入单元数:\n");
scanf_s("%d", &danyuan);
int **y;
y = (int **)malloc(sizeof(int *) * danyuan);
for (i = 0; i < line; i++) {
y[i] = (int*)malloc(sizeof(int) * 3);
}
printf("请依次输入组成单元的节点:\n");
for( i=0;i<danyuan;i++)
scanf_s("%d%d%d", &y[i][0],&y[i][1],&y[i][2]);
//定义整体刚度矩阵
double **K;
K = (double **)malloc(sizeof(double *) * (2*line));
for (i = 0; i < (2*line); i++) {
K[i] = (double*)malloc(sizeof(double) * (2*line));
}
for(i=0;i<2*line;i++)
for(j=0;j<2*line;j++)
K[i][j]=0;
//计算刚度矩阵
double p[3][2];
memset(p, 0.0, sizeof(p));
for(int m=0;m<danyuan;m++){
for( i=0;i<3;i++){
for( j=0;j<2;j++)
p[i][j]=x[y[m][i]-1][j];}
double **ki;
ki=gd ( p, t, E, u);
for( i=0;i<3;i++)
for(j=0;j<3;j++){
K[2*y[m][i]-2][2*y[m][j]-2]+=ki[2*i][2*j];
K[2*y[m][i]-1][2*y[m][j]-2]+=ki[2*i+1][2*j];
K[2*y[m][i]-2][2*y[m][j]-1]+=ki[2*i][2*j+1];
K[2*y[m][i]-1][2*y[m][j]-1]+=ki[2*i+1][2*j+1];}
}
//输出刚度矩阵
printf("整体刚度矩阵:\n");
print1(K,2*line,2*line);
//输入等效荷载矩阵
double *P;
P = (double *)malloc(sizeof(double ) * (2*line));
printf("请依次输入等效节点荷载:\n");
for(i=0;i<line;i++){
printf("节点%d:\n",i+1);
scanf_s("%lf%lf", &P[2*i],&P[2*i+1]);}
//给定边界条件
double *U;
U = (double *)malloc(sizeof(double ) * (2*line));
int RANK=2*line;
printf("请输入边界条件(位移为0时输入0,不为0时输入1):\n");
for(i=0;i<2*line;i++)
scanf_s("%lf",&U[i]);
for(i=0;i<2*line;i++){
if(U[i]==0){
for(int m=0;m<2*line;m++)
{K[m][i]=0.0;
K[i][m]=0.0;}
P[i]=0.0;
K[i][i]=1.0;}
}
for(i=0;i<2*line;i++)
U[i]=0;
//计算节点位移
double get_A = 0.0;
printf("利用以上A与b组成的增广阵进行高斯消去法计算方程组\n");
for (int i = 1; i < RANK; i++)
{
for (int j = i; j<RANK; j++)
{
get_A = K[j][i - 1] / K[i - 1][i - 1];
P[j] = P[j] - get_A * P[i - 1];
for (int k = i-1; k < RANK; k++)
{
K[j][k] = K[j][k] - get_A * K[i-1][k];
}
}
}
printf("顺序消元后的上三角系数增广矩阵如下\n");
for (int i = 0; i < RANK; i++)
{
for (int j = 0; j<RANK; j++)
{
printf("%g\t", K[i][j]);
}
printf(" %g", P[i]);
printf("\n");
}
printf("节点位移:\n");
for (int i = 0; i < RANK; i++)
{
double get_x = 0.0;
for (int j = 0; j < RANK; j++)
{
get_x = get_x + K[RANK-1-i][j]*U[j];
}
U[RANK - 1 - i] = (P[RANK - 1 - i] - get_x + K[RANK - 1 - i][RANK - 1 - i] * U[RANK - 1 - i]) / K[RANK - 1 - i][RANK - 1 - i];
}
for (int i = 0; i < RANK; i++)
{
printf("x%d = %g\n", i + 1, U[i]);
}
//计算单元应变应力
for(int m=0;m<danyuan;m++){
for( i=0;i<3;i++){
for( j=0;j<2;j++)
p[i][j]=x[y[m][i]-1][j];}
double *v;
v = (double *)malloc(sizeof(double ) * (6));
for(i=0;i<3;i++)
{v[2*i]=U[2*y[m][i]-2];
v[2*i+1]=U[2*y[m][i]-1];
}
str( p, t, E, u,v,m+1);
}
system("pause");
return 0;
}