求解的是一個圓管的徑向受壓問題,圓管的形狀如圖所示,加載的邊界條件可以在數據文件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;
}