二維彈性問題的邊界元法(C++實現)

    

    求解的是一個圓管的徑向受壓問題,圓管的形狀如圖所示,加載的邊界條件可以在數據文件data.dat中找到,需要說明的是邊界條件的給定,1表示給出了面力,0表示給出了位移。每個點有x、y兩個方向的邊界條件和變量,這跟代碼中的kode[2*i-1]和kode[2*i]是一一對應的。具體的代碼實現如下,矩陣求解用的高斯消元法。精度還算不錯吧。


data.dat文件的下載地址爲:http://pan.baidu.com/s/1pJDEha7


數據第一行一次爲:邊界上單元的個數、內部點的個數、剪切模量、泊松比


本人水平有限,若有錯誤還請指出,本人感激不盡!

#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
using namespace std;

int N,L;
double *X,*Y,*XM,*YM,XNU,GE;
double *CX,*CY,*CXM,*CYM;
double **G,**H,*DFI,*FI;
int *KODE;

void ReadData()
{
	ifstream read;
	read.open("data.dat",ios::out);
	int i,j;
	read>>N>>L>>GE>>XNU;

	//Initial Parameter
	X=new double[N+2];
	Y=new double[N+2];
	XM=new double[N+1];
	YM=new double[N+1];

	CX=new double[L+2];
	CY=new double[L+2];

	KODE=new int[2*N+1];
	DFI=new double[2*N+1];
	FI=new double[2*N+1];

	G=new double *[2*N+1];
	H=new double *[2*N+1];
	for (i=0;i<=2*N;i++)
	{
		G[i]=new double [2*N+1];
		H[i]=new double [2*N+1];
	}

	for (i=1;i<=2*N;i++)
	{
		for (j=1;j<=2*N;j++)
		{
			G[i][j]=0.0;
			H[i][j]=0.0;
		}
	}

	//Read Outer Point`s X,Y
	for (i=1;i<=N;i++)
	{
		read>>X[i]>>Y[i];
	}
	X[N+1]=X[1];
	Y[N+1]=Y[1];
	for (i=1;i<=N;i++)
	{
		XM[i]=(X[i]+X[i+1])/2.0;
		YM[i]=(Y[i]+Y[i+1])/2.0;
	}

	//Read Boundary Condition Value
	for (i=1;i<=N;i++)
	{
		read>>KODE[2*i-1]>>FI[2*i-1]>>KODE[2*i]>>FI[2*i];
	}
	/*
	//Read Inner Point`s X,Y
	for (i=1;i<=L;i++)
	{
		read>>CX[i]>>CY[i];
	}
	*/
}

void HGIJ(double xp,double yp,double x1,double y1,double x2,double y2,
	double &h11,double &h12,double &h21,double &h22,
	double &g11,double &g12,double &g21,double &g22)
{
	double gi[5],wi[5];
	double ax,ay,bx,by,el,e1,e2,ta,dist,sig;
	double de,xk,yk,ra,r1,r2;

	gi[1]=0.86113631;gi[2]=-gi[1];
	gi[3]=0.33998104;gi[4]=-gi[3];

	wi[1]=0.34785485;wi[2]=wi[1];
	wi[3]=0.65214515;wi[4]=wi[3];

	ax=(x2-x1)/2.0;
	ay=(y2-y1)/2.0;
	bx=(x2+x1)/2.0;
	by=(y2+y1)/2.0;
	el=sqrt(ax*ax+ay*ay);
	e1=ay/el;
	e2=-ax/el;

	if (abs(ax)>1e-10)
	{
		ta=ay/ax;
		dist=abs((ta*xp-yp+y1-ta*x1)/sqrt(ta*ta+1.0));
	}
	else
	{
		dist=abs(xp-x1);
	}
	sig=(x1-xp)*(y2-yp)-(x2-xp)*(y1-yp);
	if (sig<0.0)
	{
		dist=-dist;
	}
	h11=0.0;h12=0.0;
	h21=0.0;h22=0.0;

	g11=0.0;g12=0.0;
	g21=0.0;g22=0.0;
	de=4.0*3.141592653*(1.0-XNU);
	int k;
	for (k=1;k<=4;k++)
	{
		xk=ax*gi[k]+bx;
		yk=ay*gi[k]+by;
		ra=sqrt(pow(xp-xk,2)+pow(yp-yk,2));
		r1=(xk-xp)/ra;
		r2=(yk-yp)/ra;
		g11+=el*((3.0-4*XNU)*log(1.0/ra)+r1*r1)*wi[k]/(2.0*de*GE);
		g12+=el*r1*r2*wi[k]/(2.0*de*GE);
		g22+=el*((3.0-4.0*XNU)*log(1.0/ra)+r2*r2)*wi[k]/(2.0*de*GE);

		h11-=dist*el*((1.0-2.0*XNU)+2.0*r1*r1)*wi[k]/(ra*ra*de);
		h12-=el*(dist*2*r1*r2/ra-(1.0-2.0*XNU)*(e2*r1-e1*r2))*wi[k]/(ra*de);
		h21-=el*(dist*2*r1*r2/ra-(1.0-2.0*XNU)*(e1*r2-e2*r1))*wi[k]/(ra*de);
		h22-=dist*el*((1.0-2.0*XNU)+2.0*r2*r2)*wi[k]/(ra*ra*de);
	}
	g21=g12;
}

void HGII(double x1,double y1,double x2,double y2,
	double &h11,double &h12,double &h21,double &h22,
	double &g11,double &g12,double &g21,double &g22)
{
	double ax,ay,el,de;

	ax=(x2-x1)/2.0;
	ay=(y2-y1)/2.0;
	el=sqrt(ax*ax+ay*ay);
	de=4.0*3.141592653*GE*(1.0-XNU);

	g11=el*((3.0-4.0*XNU)*(1.0-log(el))+ax*ax/(el*el))/de;
	g12=ax*ay/(el*de);
	g22=el*((3.0-4.0*XNU)*(1.0-log(el))+ay*ay/(el*el))/de;
	g21=g12;

	h11=0.5;h12=0.0;
	h21=0.0;h22=0.5;
}

void FMAT()
{
	int i,j;
	for (i=1;i<=N;i++)
	{
		for (j=1;j<=N;j++)
		{
			if (i==j)
			{
				HGII(X[j],Y[j],X[j+1],Y[j+1],
					H[2*i-1][2*j-1],H[2*i-1][2*j],H[2*i][2*j-1],H[2*i][2*j],
					G[2*i-1][2*j-1],G[2*i-1][2*j],G[2*i][2*j-1],G[2*i][2*j]);
			}
			else
			{
				HGIJ(XM[i],YM[i],X[j],Y[j],X[j+1],Y[j+1],
					H[2*i-1][2*j-1],H[2*i-1][2*j],H[2*i][2*j-1],H[2*i][2*j],
					G[2*i-1][2*j-1],G[2*i-1][2*j],G[2*i][2*j-1],G[2*i][2*j]);
			}
		}
	}
	double temp;
	for (j=1;j<=2*N;j++)
	{
		if (KODE[j]==1)
		{
			for (i=1;i<=2*N;i++)
			{
				temp=G[i][j];
				G[i][j]=-H[i][j];
				H[i][j]=-temp;
			}
		}
		
		else
		{
			for (i=1;i<=2*N;i++)
			{
				G[i][j]=G[i][j]*GE;
			}
		}
		
	}

	for (i=1;i<=2*N;i++)
	{
		DFI[i]=0.0;
		for (j=1;j<=2*N;j++)
		{
			DFI[i]+=H[i][j]*FI[j];
		}
	}
}

int Gauss()
{
	long i,j,k,l,m;
	long n = 2*N;
	double d,t;
	long* ID = new long[n+1];

	l=1;
	for(k=1;k<=n-1;++k)
	{ 
		d=0.0;
		for(i=k;i<=n;++i)
			for(j=k;j<=n;++j)
			{ 
				t=G[i][j]*G[i][j];
				if (t>d) 
				{d=t; ID[k]=j; m=i;}
			}
			if(d+1.0==1.0) 
				l=0;
			else
			{ 
				if(ID[k]!=k)
					for(i=1;i<=n;++i)
					{t=G[i][k]; G[i][k]=G[i][ID[k]]; G[i][ID[k]]=t;}
					if(m!=k)
					{
						for(j=k;j<=n;++j)
						{
							t=G[k][j];
							G[k][j]=G[m][j];
							G[m][j]=t;
						}
						t=DFI[k];
						DFI[k]=DFI[m];
						DFI[m]=t;
					}
			}
			if(l==0)
			{
				delete[] ID;
				return 0;
			}
			d=G[k][k];
			for(j=k+1;j<=n;++j)
			{
				G[k][j]=G[k][j]/d;
			}
			DFI[k]=DFI[k]/d;
			for(i=k+1;i<=n;++i)
			{ 
				for(j=k+1;j<=n;++j)
				{
					G[i][j]=G[i][j]-G[i][k]*G[k][j];
				}
				DFI[i]=DFI[i]-G[i][k]*DFI[k];
			}
	}
	d=G[n][n];
	if(d+1.0==1.0)
	{
		delete[] ID;
		return 0;
	}
	DFI[n]=DFI[n]/d;
	for(i=n-1;i>=1;--i)
	{ 
		t=0.0;
		for(j=i+1;j<=n;++j)
		{
			t+=G[i][j]*DFI[j];
		}
		DFI[i]=DFI[i]-t;
	}
	ID[n]=n;
	for(k=n;k>=1;--k)
		if(ID[k]!=k)
		{
			t=DFI[k];
			DFI[k]=DFI[ID[k]];
			DFI[ID[k]]=t;
		}
		delete[] ID;
		return 1;
}

void ReOrder()
{
	int i,j;
	double temp;
	for (i=1;i<=2*N;i++)
	{
		if (KODE[i]==1)
		{
			temp=FI[i];
			FI[i]=DFI[i];
			DFI[i]=temp;
		}
		
		else
		{
			DFI[i]=DFI[i]*GE;
		}
		
	}
}

void OutPut()
{
	ofstream out;
	out.open("result.dat",ios::out);
	int i,j;
	
	out<<"X          Y          U1          U2          Un1          Un2"<<endl;
	for (i=1;i<=N;i++)
	{
		
		out<<setiosflags(ios::scientific)<<setprecision(3)
			<<XM[i]<<" "<<YM[i]<<" "<<FI[2*i-1]<<" "<<FI[2*i]<<" "
		<<DFI[2*i-1]<<" "<<DFI[2*i]<<endl;
		
		/*
		out<<XM[i]<<"  "<<YM[i]<<"  "<<FI[2*i-1]<<"  "<<FI[2*i]<<"  "
			<<DFI[2*i-1]<<"  "<<DFI[2*i]<<endl;
			*/
	}

	out.close();
}

int main()
{
	ReadData();
	FMAT();
	if (Gauss())
	{
		cout<<"Complete Successful!"<<endl;
		ReOrder();
		OutPut();
	}
	else
	{
		cout<<"Guass Compute Failed!"<<endl;
	}
	return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章