⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shenliu.cpp

📁 有限元计算基本程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <iostream.h>

int Gauss(double a[],double b[],int n);	//全选主元高斯消去法

struct ETNode{							//单元结点结构体
	double x,y;							//单元结点坐标
	int number;							//单元结点在总体区域划分中的编号
};


struct ElementTriangle{					//三角形单元结构体	
	ETNode nd[3];						//存储相对应的单元结点号
	double	a[3],b[3],c[3];				//基函数的系数
	double	A;							//单元面积
	double	Aij[3][3];					//单元有限元特征式系数矩阵
};

struct  Modulus_penetr{                //地层的渗透系数
	int  material;                     //地层编号
	char name_mat[15];                   //地层名称
	double B[2][2];                    //渗透系数
};

struct Char_infile{                    //输入文件中的注释字符
	char title[30];
};

struct Border{                         //边界条件
	int  jd;                           //节点编号
	double dx;                         //水头大小
};

//struct ETNoded{							//迭代增加的单元结点结构体
//	double x,y;							//单元结点坐标
//	int number;							//单元结点在总体区域划分中的编号
//};

struct Border_ele{                       //边界单元结构体
	int a,b,c,d;
};


 

//--------------  全局变量  ---------------------------
	int	i,j,k,l,m,							//循环指标
		id;	                                //单元的循环指标
//    int iN[13];                          //注意改变数组的大小(节点总数)
	int Ele[19];                         //注意改变数组的大小(单元总数)
	double zhi[16];                       //注意改变数组的大小(节点总数)
	double  tem[16];                       //注意改变数组的大小(节点总数)
//	int  tem1[4];                          //注意改变数组的大小(可能的出水节点总数)
//	int  sum_border_ele;                 //边界单元的各数
//	int  jinshui_point;                 //进水点节点编号

	int num_border;                     //已知水头节点的总数
	int num_waterout;                   //可能出水点的节点总数
	int outpoint[200];                  //可能出水节点
	int sum_material;                   //地层渗透系数种类
	int place_mat[40][3];               //不同地层分布位置
	double	D;							//单元矩阵行列式值
	int iNode,element;                  //节点数和单元数
	
//	ElementTriangle* pE;				//单元三角形结构体数组指针

	double ai,bi,ci;					//基函数的系数
	double water_error;                 //自由水面误差结束标准
	



//--------------------  主程序  -------------------------//
void main()
{
    struct Char_infile *chf=new Char_infile[13];                     //输入文件注释结构数组指针及分配内存
	struct Border *bl=new Border[400];                                //边界条件,结构数组指针及分配内存
	FILE *cfptr;
    if ((cfptr=fopen("shu.dat","r"))==NULL)
		printf("无法打开文件.\n");
	else
		fscanf(cfptr,"%s",chf[0].title);
	    fscanf(cfptr,"%s",chf[1].title);
		fscanf(cfptr,"%d",&iNode);
   		fscanf(cfptr,"%s",chf[2].title);
		fscanf(cfptr,"%d",&element);

     //为总体矩阵,三角形单元数组,f函数向量等分配存储内存

//	pE=(ElementTriangle*)malloc(element*sizeof(ElementTriangle));
//	cnode=(ETNode*)malloc(iNode*sizeof(ETNode));
	double *pMatrix=new double[iNode*iNode*sizeof(double)];				//总体矩阵指针
	double *pMf=new double[iNode*sizeof(double)];						//f向量指针
	struct ElementTriangle *pE=new ElementTriangle[element];            //单元
	struct ETNode *cnode=new ETNode[iNode];                     //存坐标

	////"50"为认为规定迭代次数,要求计算次数较多的,根据情况自行改变此值//

	//初始化值为0,因为下面要累加总体矩阵
	for(i=0;i<iNode*iNode;i++)
		pMatrix[i]=0;
	for(i=0;i<iNode;i++)
		pMf[i]=0;

		fscanf(cfptr,"%s",chf[3].title);
		fscanf(cfptr,"%lf",&water_error);
		fscanf(cfptr,"%s",chf[4].title);
        for(i=0;i<element;i++)
			fscanf(cfptr,"%d    %d     %d    %d",&Ele[i],&pE[i].nd[0].number,&pE[i].nd[1].number,&pE[i].nd[2].number);
		fscanf(cfptr,"%s",chf[5].title);
	    for(j=0;j<iNode;j++)
			fscanf(cfptr,"%d    %lf    %lf",&cnode[j].number,&cnode[j].x,&cnode[j].y);
		 for(i=0;i<element;i++)
		{  
			pE[i].nd[0].x=cnode[pE[i].nd[0].number].x;
			pE[i].nd[0].y=cnode[pE[i].nd[0].number].y;
			pE[i].nd[1].x=cnode[pE[i].nd[1].number].x;
		    pE[i].nd[1].y=cnode[pE[i].nd[1].number].y;
			pE[i].nd[2].x=cnode[pE[i].nd[2].number].x;
			pE[i].nd[2].y=cnode[pE[i].nd[2].number].y;
		}
		fscanf(cfptr,"%s",chf[6].title);
        fscanf(cfptr,"%d",&num_border);
		fscanf(cfptr,"%s",chf[7].title);
		for(k=0;k<num_border;k++)                      
			fscanf(cfptr,"%d    %lf",&bl[k].jd,&bl[k].dx);
        fscanf(cfptr,"%s",chf[8].title);
        fscanf(cfptr,"%d",&num_waterout);
		fscanf(cfptr,"%s",chf[9].title);
		for(m=0;m<num_waterout;m++)                           
			fscanf(cfptr,"%d",&outpoint[m]);
		fscanf(cfptr,"%s",chf[10].title);
		fscanf(cfptr,"%d",&sum_material);
		fscanf(cfptr,"%s",chf[11].title);

    struct  Modulus_penetr *mp=new Modulus_penetr[sum_material];     //不同地层的渗透系数,结构数组指针及分配内存

		for(id=0;id<sum_material;id++)
		{
			fscanf(cfptr,"%d    %s",&mp[id].material,mp[id].name_mat);
			fscanf(cfptr,"%lf   %lf",&mp[id].B[0][0],&mp[id].B[0][1]);
			fscanf(cfptr,"%lf   %lf",&mp[id].B[1][0],&mp[id].B[1][1]);
		}
		fscanf(cfptr,"%s",chf[12].title);
		for(l=0;l<sum_material;l++)
			fscanf(cfptr,"%d    %d    %d",&place_mat[l][0],&place_mat[l][1],&place_mat[l][2]);

///	输出读入的文件数据
		printf("%s\n",chf[0].title);
	    printf("%s\n",chf[1].title);
		printf("%d\n",iNode);
		printf("%s\n",chf[2].title);
		printf("%d\n",element);
		printf("%s\n",chf[3].title);
		printf("%E\n",water_error);
		printf("%s\n",chf[4].title);
		for(i=0;i<element;i++)
			printf("%d    %d     %d    %d\n",Ele[i],pE[i].nd[0].number,pE[i].nd[1].number,pE[i].nd[2].number);
		printf("%s\n",chf[5].title);
		for(j=0;j<iNode;j++)
			printf("%d    %lf    %lf\n",cnode[j].number,cnode[j].x,cnode[j].y);
		printf("%s\n",chf[6].title);
        printf("%d\n",num_border);
	    printf("%s\n",chf[7].title);
		for(k=0;k<num_border;k++)                              
	         printf("%d    %lf\n",bl[k].jd,bl[k].dx);
		printf("%s\n",chf[8].title);
        printf("%d\n",num_waterout);
		printf("%s\n",chf[9].title);
		for(m=0;m<num_waterout;m++)                              
			printf("%d\n",outpoint[m]);
		printf("%s\n",chf[10].title);
		printf("%d\n",sum_material);
		printf("%s\n",chf[11].title);
		for(id=0;id<sum_material;id++)
		{
			printf("%d    %s\n",mp[id].material,mp[id].name_mat);
			printf("%lf   %lf\n",mp[id].B[0][0],mp[id].B[0][1]);
			printf("%lf   %lf\n",mp[id].B[1][0],mp[id].B[1][1]);
		}
		printf("%s\n",chf[12].title);
		for(l=0;l<sum_material;l++)
			printf("%d    %d    %d\n",place_mat[l][0],place_mat[l][1],place_mat[l][2]);
	
		printf("节点信息.\n");
		for(i=0;i<element;i++)
		{  
			printf("%d   %lf    %lf\n",pE[i].nd[0].number,pE[i].nd[0].x,pE[i].nd[0].y);
		
			printf("%d   %lf    %lf\n",pE[i].nd[1].number,pE[i].nd[1].x,pE[i].nd[1].y);
			
			printf("%d   %lf    %lf\n\n",pE[i].nd[2].number,pE[i].nd[2].x,pE[i].nd[2].y);
		
		}


try{
	
	printf("计算基函数系数值...\n");
	for(id=0;id<element;id++)
	{
		for(i=0;i<3;i++)
		{
			if(i==0)		j=1,k=2;
			else if(i==1)	j=2,k=0;
			else if(i==2)	j=0,k=1;
			
			pE[id].A=( (pE[id].nd[j].x-pE[id].nd[i].x)*(pE[id].nd[k].y-pE[id].nd[i].y)-
				(pE[id].nd[j].y-pE[id].nd[i].y)*(pE[id].nd[k].x-pE[id].nd[i].x) )/2.0;
			D=2.0*pE[id].A;
			pE[id].a[i]=( pE[id].nd[j].x*pE[id].nd[k].y- pE[id].nd[k].x*pE[id].nd[j].y )/D;
			pE[id].b[i]=( pE[id].nd[j].y-pE[id].nd[k].y )/D;
			pE[id].c[i]=( pE[id].nd[k].x-pE[id].nd[j].x )/D;

		}
	}
	printf("OK!\n");

	printf("计算单元有限元特征式系数矩阵...\n");

    for(j=0;j<sum_material;j++)
	{
		for(i=place_mat[j][0];i<=place_mat[j][1];i++)
		{
			for(l=0;l<3;l++)				                  
				for(m=0;m<3;m++)
				{
				pE[i].Aij[l][m]=( pE[i].b[l]*pE[i].b[m]*mp[j].B[0][0] + 
					pE[i].c[l]*pE[i].c[m]*mp[j].B[1][1])*pE[i].A;
				}
		}
	}

	printf("OK!\n");
    
	//单元矩阵元素累加到总体矩阵相应的位置上////////////////////////////////////////////////////	
	printf("单元矩阵元素累加到总体矩阵相应的位置上...\n");
	
	
	for(int idx=0;idx<element;idx++)		
		for(i=0;i<3;i++)
		{
			for(j=0;j<3;j++)
			{pMatrix[ pE[idx].nd[i].number*iNode+pE[idx ].nd[j].number] += pE[idx].Aij[i][j];
			}
		pMf[ pE[idx].nd[i].number ]=0;
		}


	printf("OK!\n");

    ///////////边界条件的处理////////////
    printf("边界条件的处理...\n");

	double dBig=pow(10,25);				    //边界条件对角线扩大法处理所用的大数
	for(k=0;k<num_border;k++)                          
	{   
		pMatrix[bl[k].jd*iNode+bl[k].jd] *= dBig;
	    pMf[bl[k].jd]=pMatrix[bl[k].jd*iNode+bl[k].jd]*bl[k].dx;
	}
	
	printf("OK!\n");


/////////////////////////////////////////////////////////////////////////////////

	printf("调用全选主元高斯消去法函数解方程组...\n");
	Gauss(pMatrix,pMf,iNode);			         //调用全选主元高斯消去法函数解方程组
	for(i=0;i<iNode;i++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -