此方法解九对角矩阵
根据
A modified strongly implicit procedure for the numerical solution of field problems
GE Schneider, M Zedan - Numerical Heat Transfer, 1981 - Taylor & Francis
的思路,原文看不到
参考 计算传热学近代进展 (书上公式有误)
// MSIP.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" double abs(double a){ if(a>=0){ return a; }else{ return -a; } } int MSIPsolver(double *Aa, double *Ab, double *Ac, double *Ad, double *Ae, double *Af, double *Ag, double *Ah, double *As, double *x,double* r, int m,int n) { double ALF=0.6; double P1=0; double P2=0; double *La,*Lb,*Lc,*Ld,*Le,*Uf,*Ug,*Uh,*Us; double *RES; double RESN=0; int MAXITER=1000; int ITER; La=new double [n+1]; Lb=new double [n+1]; Lc=new double [n+1]; Ld=new double [n+1]; Le=new double [n+1]; Uf=new double [n+1]; Ug=new double [n+1]; Uh=new double [n+1]; Us=new double [n+1]; RES=new double [n+1]; for(int i=0;i<=n;i++){ La[i]=0; Lb[i]=0; Lc[i]=0; Ld[i]=0; Le[i]=0; Uf[i]=0; Ug[i]=0; Uh[i]=0; Us[i]=0; RES[i]=0; } for(int i=0;i<=n;i++) { //La----------------- if(i>=m+1){ La[i]= Aa[i]; }else{ La[i]=0; } //Lb----------------- if(i>=m){ Lb[i]= Ab[i] - La[i]*Uf[i-m-1] - ALF*Lc[i]*Uf[i-m+1]; }else{ Lb[i]=0; } //Lc----------------- if(i>=m-1){ Lc[i]= Ac[i] - Lb[i]*Uf[i-m]; }else{ Lc[i]= 0; } //Ld----------------- if(i>=1){ Ld[i]= (Ad[i] - La[i]*Uh[i-m-1] - Lb[i]*Ug[i-m] - 2*ALF*La[i]*Ug[i-m-1])/(2*ALF*Ug[i-1] + 1); }else{ Ld[i]=0; } //Le----------------- Le[i]= Ae[i] - Lb[i]*Uh[i-m] - Lc[i]*Ug[i-m+1] - Ld[i]*Uf[i-1] - La[i]*Us[i-m-1] + ALF*La[i]*Ug[i-m-1] - 2*ALF*Lc[i]*Uf[i-m+1] + 2*ALF*Ld[i]*Ug[i-1] + ALF*Lc[i]*Us[i-m+1]; //Uf----------------- if(i<=n-1){ Uf[i]= (Af[i] - Lc[i]*Uh[i-m+1] - Lb[i]*Us[i-m] + 2*ALF*Lc[i]*Uf[i-m+1] - 2*ALF*Lc[i]*Us[i-m+1])/Le[i]; }else{ Uf[i]=0; } //Ug----------------- if(i<=n-m+1){ Ug[i]= (Ag[i] - Ld[i]*Uh[i-1])/Le[i]; }else{ Ug[i]=0; } //Uh----------------- if(i<=n-m){ Uh[i]= (Ah[i] - Ld[i]*Us[i-1] - ALF*Ld[i]*Ug[i-1])/Le[i]; }else{ Uh[i]=0; } //Us----------------- if(i<=n-m-1){ Us[i]= As[i]/Le[i]; }else{ Us[i]= 0; } } ITER=0; do{ RESN=0; for(int i=0;i<=n;i++) { RES[i]=r[i]-(Aa[i]*(i-m-1>=0?x[i-m-1]:0) +Ab[i]*(i-m>=0?x[i-m]:0) +Ac[i]*(i-m+1>=0?x[i-m+1]:0) +Ad[i]*(i-1>=0?x[i-1]:0) +Ae[i]*x[i] +Af[i]*(i+1<=n?x[i+1]:0) +Ag[i]*(i+m-1<=n?x[i+m-1]:0) +Ah[i]*(i+m<=n?x[i+m]:0) +As[i]*(i+m+1<=n?x[i+m+1]:0)); RESN+=abs(RES[i]); } for(int i=0;i<=n;i++) { RES[i]=(RES[i]-La[i]*(i-m-1>=0?RES[i-m-1]:0) -Lb[i]*(i-m>=0?RES[i-m]:0) -Lc[i]*(i-m+1>=0?RES[i-m+1]:0) -Ld[i]*(i-1>=0?RES[i-1]:0))/Le[i]; } for(int i=n;i>=0;i--) { x[i]=x[i]+(RES[i]-Uf[i]*(i+1<=n?RES[i+1]:0) -Ug[i]*(i+m-1<=n?RES[i+m-1]:0) -Uh[i]*(i+m<=n?RES[i+m]:0) -Us[i]*(i+m+1<=n?RES[i+m+1]:0)); } ITER++; }while(abs(RESN)>1E-6&&ITER<MAXITER); delete [] La; delete [] Lb; delete [] Lc; delete [] Ld; delete [] Le; delete [] Uf; delete [] Ug; delete [] Uh; delete [] Us; delete [] RES; return ITER>MAXITER?-1:1; } int _tmain(int argc, _TCHAR* argv[]) { const int n=29; int m=6; //Define a b c d e f g h s double Aa[n+1],Ab[n+1],Ac[n+1],Ad[n+1],Ae[n+1],Af[n+1],Ag[n+1],Ah[n+1],As[n+1],x[n+1],xr[n+1],r[n+1]; for(int i=0;i<=n;i++){ i>=m+1?Aa[i]=1:Aa[i]=0; i>=m?Ab[i]=2:Ab[i]=0; i>=m-1?Ac[i]=1:Ac[i]=0; i>=1?Ad[i]=3:Ad[i]=0; Ae[i]=18; i<=n-1?Af[i]=3:Af[i]=0; i<=n-m+1?Ag[i]=1:Ag[i]=0; i<=n-m?Ah[i]=2:Ah[i]=0; i<=n-m-1?As[i]=1:As[i]=0; r[i]=i+2; x[i]=1; } for(int i=0;i<=n;i++){ printf("Aa[%d]=%.2f ",i,Aa[i]); printf("Ab[%d]=%.2f ",i,Ab[i]); printf("Ac[%d]=%.2f ",i,Ac[i]); printf("Ad[%d]=%.2f ",i,Ad[i]); printf("Ae[%d]=%.2f ",i,Ae[i]); printf("\n"); } for(int i=0;i<=n;i++){ printf("Af[%d]=%.2f ",i,Af[i]); printf("Ag[%d]=%.2f ",i,Ag[i]); printf("Ah[%d]=%.2f ",i,Ah[i]); printf("As[%d]=%.2f ",i,As[i]); printf("r[%d]=%.2f ",i,r[i]); printf("\n"); } xr[0]=0.0419; xr[1]=0.0777; xr[2]=0.1145; xr[3]=0.151; xr[4]=0.1878; xr[5]=0.2227; xr[6]=0.2534; xr[7]=0.2831; xr[8]=0.3135; xr[9]=0.3436; xr[10]=0.3741; xr[11]=0.4062; xr[12]=0.4398; xr[13]=0.4732; xr[14]=0.505; xr[15]=0.5368; xr[16]=0.569; xr[17]=0.5925; xr[18]=0.6064; xr[19]=0.6266; xr[20]=0.6551; xr[21]=0.69; xr[22]=0.705; xr[23]=0.7724; xr[24]=0.9334; xr[25]=1.0289; xr[26]=1.0547; xr[27]=1.1003; xr[28]=1.0966; xr[29]=1.3626; //for(int i=0;i<=n;i++){ // printf("xr[%d]=%.6f ",i,xr[i]); // printf("\n"); //} printf("-----------------------------\n"); MSIPsolver(Aa,Ab,Ac,Ad,Ae,Af,Ag,Ah,As,x,r,m,n); for(int i=0;i<=n;i++){ printf("x[%d]=%.6f ",i,x[i]); printf("xr[%d]=%.6f ",i,xr[i]); printf("\n"); } return 0; }