基于并行EBE-CG方法的有限元求解程序(从我的毕业论文中节选出来的)
2009-07-01 21:31
323 查看
附录A EBE-CG法主程序
/* FemPar.c
Written by XiaoFei,college of mathematics science and computing technology,CSU,2009-5 */
#include<stdio.h>
#include<malloc.h>
#include"mpi.h"
#define PROCNO 4
typedef struct
{
float Pos[2];
int Local;
int Type;
}NodeType;
typedef struct
{
int Vertex[3];
}ElementType;
NodeType *Node;
ElementType *Element;
int *Shared,MaxCommon,Common[PROCNO],*Neighbours[PROCNO];
int ProcNo,ProcID,Nodes,Elements,IntNodes,IBNodes;
float *Buf;
float InnerProduct(float *A1,float *A2,float *B1,float *B2)
{
int I;
float IP=0.0,IPTocal;
for(I=0;I<IntNodes;I++)
IP+=A1[I]*B1[I];
for(I=0;I<IBNodes;I++)
IP+=(A2[I]*B2[I])/Shared[I];
MPI_Allreduce(&IP,&IPTocal,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD);
return(IPTocal);
}
void Update(float *A)
{
int I,J;
MPI_Status Status;
for(I=0;I<PROCNO;I++)
{
for(J=0;J<Common[I];J++)
Buf[J]=A[Node[Neighbours[I][J]].Local];
if(Common[I]>0)
MPI_Send(&Buf[0],Common[I],MPI_FLOAT,I,10,MPI_COMM_WORLD);
}
for(I=0;I<PROCNO;I++)
{
if(Common[I]>0)
MPI_Recv(&Buf[0],Common[I],MPI_FLOAT,I,10,MPI_COMM_WORLD,&Status);
for(J=0;J<Common[I];J++)
A[Node[Neighbours[I][J]].Local]+=Buf[J];
}
}
int CG(float **Ap,float **As,float **Bp,float *Fp,float *Fs,float *Vp,float *Vs)
{
float *Rp,*Rs,*Pp,*Ps,*Qp,*Qs,GammaOld,GammaNew,Tau,Alpha,Beta,Tol=1.0e-4;
int I,J,K,KMax=250;
Pp=(float*)malloc(IntNodes*sizeof(float));
Ps=(float*)malloc(IBNodes*sizeof(float));
Qp=(float*)malloc(IntNodes*sizeof(float));
Qs=(float*)malloc(IBNodes*sizeof(float));
Rp=(float*)malloc(IntNodes*sizeof(float));
Rs=(float*)malloc(IBNodes*sizeof(float));
Update(Fs);
for(I=0;I<IntNodes;I++)
Pp[I]=Rp[I]=Fp[I];
for(I=0;I<IBNodes;I++)
Ps[I]=Rs[I]=Fs[I];
GammaNew=InnerProduct(Rp,Rs,Rp,Rs);
if(GammaNew<Tol*Tol)
return(1);
if(ProcID==0)
printf("Gamma = %f/n",GammaNew);
for(K=0;K<KMax;K++)
{
for(I=0;I<IntNodes;I++)
{
for(J=0,Qp[I]=0.0;J<IntNodes;J++)
Qp[I]+=Ap[I][J]*Pp[J];
for(J=0;J<IBNodes;J++)
Qp[I]+=Bp[I][J]*Ps[J];
}
for(I=0;I<IBNodes;I++)
{
for(J=0,Qs[I]=0.0;J<IntNodes;J++)
Qs[I]+=Bp[I][J]*Pp[J];
for(J=0;J<IBNodes;J++)
Qs[I]+=As[I][J]*Ps[J];
}
Update(Qs);
Tau=InnerProduct(Pp,Ps,Qp,Qs);
Alpha=GammaNew/Tau;
for(I=0;I<IBNodes;I++)
{
Vp[I]+=Alpha*Pp[I];
Rp[I]-=Alpha*Qp[I];
}
for(I=0;I<IBNodes;I++)
{
Vs[I]+=Alpha*Ps[I];
Rs[I]-=Alpha*Qs[I];
}
GammaOld=GammaNew;
GammaNew=InnerProduct(Rp,Rs,Rp,Rs);
if(ProcID==0)
printf("Gamma = %f (K = %d)/n",GammaNew,K);
if(GammaNew<Tol*Tol)
return(1);
Beta=GammaNew/GammaOld;
for(I=0;I<IntNodes;I++)
Pp[I]=Rp[I]+Beta*Pp[I];
for(I=0;I<IBNodes;I++)
Ps[I]=Rs[I]+Beta*Ps[I];
}
return(0);
}
float BC(float X,float Y)
{
return(X+Y);
}
main(int argc,char** argv)
{
FILE *InFile,*OutFile;
char FileName[40];
int I,J,K,II,JJ;
float **Ap,**Bp,**As,*Fp,*Fs,*Vp,*Vs;
float SLoc[3][2],TwoA,Area,Gr0[3],Gr1[3],StiffJI;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&ProcID);
MPI_Comm_size(MPI_COMM_WORLD,&ProcNo);
if(ProcNo!=PROCNO)
{
printf("Unexpected number of processors./n");
MPI_Abort(MPI_COMM_WORLD,-1);
}
if(ProcID<10)
sprintf(FileName,"Data0%d.In",ProcID);
else
sprintf(FileName,"Data%d.In",ProcID);
InFile=fopen(FileName,"r");
fscanf(InFile,"%d%d",&Nodes,&Elements);
Node=(NodeType*)malloc(Nodes*sizeof(NodeType));
for(I=0,IntNodes=0,IBNodes=0;I<Nodes;I++)
{
fscanf(InFile,"%f%f%d",&Node[I].Pos[0],&Node[I].Pos[1],&Node[I].Type);
if(Node[I].Type==1)
Node[I].Local=IntNodes++;
else if(Node[I].Type>1)
Node[I].Local=IBNodes++;
else
Node[I].Local=-1;
}
Shared=(int*)malloc(IBNodes*sizeof(int));
for(I=0,IBNodes=0;I<Nodes;I++)
if(Node[I].Type>1)
Shared[IBNodes++]=Node[I].Type;
Element=(ElementType*)malloc(Elements*sizeof(ElementType));
for(I=0;I<Elements;I++)
fscanf(InFile,"%d%d%d",&Element[I].Vertex[0],&Element[I].Vertex[1],&Element[I].Vertex[2]);
MaxCommon=0;
for(I=0;I<PROCNO;I++)
{
fscanf(InFile,"%d",&Common[I]);
if(Common[I]>MaxCommon)
MaxCommon=Common[I];
if(Common[I]>0)
Neighbours[I]=(int*)malloc(Common[I]*sizeof(int));
for(J=0;J<Common[I];J++)
fscanf(InFile,"%d",&Neighbours[I][J]);
}
Buf=(float*)malloc(MaxCommon*sizeof(float));
fclose(InFile);
printf("ProcID = %d,IntNodes = %d,IBNodes = %d/n",ProcID,IntNodes,IBNodes);
Ap=(float**)calloc(IntNodes,sizeof(float*));
for(I=0;I<IntNodes;I++)
Ap[I]=(float*)calloc(IntNodes,sizeof(float));
Bp=(float**)calloc(IBNodes,sizeof(float*));
for(I=0;I<IntNodes;I++)
Bp[I]=(float*)calloc(IntNodes,sizeof(float));
As=(float**)calloc(IBNodes,sizeof(float*));
for(I=0;I<IBNodes;I++)
As[I]=(float*)calloc(IBNodes,sizeof(float));
Fp=(float*)calloc(IntNodes,sizeof(float));
Fs=(float*)calloc(IBNodes,sizeof(float));
Vp=(float*)calloc(IntNodes,sizeof(float));
Vs=(float*)calloc(IBNodes,sizeof(float));
for(K=0;K<Elements;K++)
{
SLoc[0][0]=Node[Element[K].Vertex[0]].Pos[0];
SLoc[1][0]=Node[Element[K].Vertex[1]].Pos[0];
SLoc[2][0]=Node[Element[K].Vertex[2]].Pos[0];
SLoc[0][1]=Node[Element[K].Vertex[0]].Pos[1];
SLoc[1][1]=Node[Element[K].Vertex[1]].Pos[1];
SLoc[2][1]=Node[Element[K].Vertex[2]].Pos[1];
TwoA=SLoc[0][0]*(SLoc[1][1]-SLoc[2][1])+
SLoc[1][0]*(SLoc[2][1]-SLoc[0][1])+
SLoc[2][0]*(SLoc[0][1]-SLoc[1][1]);
Area=0.5*TwoA;
Gr0[0]=(SLoc[1][1]-SLoc[2][1])/TwoA;
Gr0[1]=(SLoc[2][1]-SLoc[0][1])/TwoA;
Gr0[2]=(SLoc[0][1]-SLoc[1][1])/TwoA;
Gr0[0]=-(SLoc[1][0]-SLoc[2][0])/TwoA;
Gr0[1]=-(SLoc[2][0]-SLoc[0][0])/TwoA;
Gr0[2]=-(SLoc[0][0]-SLoc[1][0])/TwoA;
for(J=0;J<3;J++)
{
JJ=Element[K].Vertex[J];
if(Node[JJ].Type==1)
for(I=0;I<3;I++)
{
II=Element[K].Vertex[I];
StiffJI=Area*(Gr0[I]*Gr0[J]+Gr1[I]*Gr1[J]);
if(Node[II].Type==1)
Ap[Node[JJ].Local][Node[II].Local]+=StiffJI;
else
if(Node[II].Type>1)
Bp[Node[JJ].Local][Node[II].Local]+=StiffJI;
else
if(Node[II].Type==0)
Fp[Node[JJ].Local]-=BC(Node[II].Pos[0],Node[II].Pos[1])*StiffJI;
}
else
if(Node[JJ].Type>1)
for(I=0;I<3;I++)
{
II=Element[K].Vertex[I];
StiffJI=Area*(Gr0[I]*Gr0[J]+Gr1[I]*Gr1[J]);
if(Node[II].Type>1)
As[Node[JJ].Local][Node[II].Local]+=StiffJI;
else
if(Node[JJ].Type==0)
Fs[Node[JJ].Local]-=BC(Node[II].Pos[0],Node[II].Pos[1])*StiffJI;
}
}
}
CG(Ap,As,Bp,Fp,Fs,Vp,Vs);
for(I=0;I<Nodes;I++)
if(Node[I].Type==1)
printf(" %f %f %f/n",Node[I].Pos[0],Node[I].Pos[1],Vp[Node[I].Local]);
else
if(Node[I].Type>1)
printf(" %f %f %f/n",Node[I].Pos[0],Node[I].Pos[1],Vs[Node[I].Local]);
MPI_Finalize();
}
附录B 任务分配预处理程序
#include<stdio.h>
#define FILENAME "mesh.txt"
#define PROCNO 4
typedef struct{
float Pos[2]; //位置坐标
int GlobalDOF;
int LocalNode;
int Type;
}NodeType;
typedef struct{
int Vertex[3];
}ElementType;
NodeType* Node;
ElementType* Element;
int PartSize[PROCNO],*PartE[PROCNO],*PartN[PROCNO];
main(int argc,char** argv)
{
FILE *InFile,*OutFile;
int Nodes,Elements,I,J,K,V,NodeCounter[PROCNO],Common[PROCNO];
char FileName[40];
InFile=fopen(FILENAME,"r");
//读入节点信息
fscanf(InFile,"%d",&Nodes);//节点数目
Node=(NodeType*)malloc(Nodes*sizeof(NodeType));
for(I=0;I<PROCNO;I++)
PartN[I]=(int*)malloc(Nodes*sizeof(int));
for(I=0;I<Nodes;I++)
{
fscanf(InFile,"%d%f%f",&Node[I].GlobalDOF,&Node[I].Pos[0],&Node[I].Pos[1]);
//读入节点GlobalDOF,坐标,
Node[I].Type=0;
//初始化节点符号,<0表示边界
}
//读入单元信息
fscanf(InFile,"%d",&Elements); //单元数目
Element=(ElementType*)malloc(Elements*sizeof(ElementType));
for(I=0;I<PROCNO;I++)
{
PartE[I]=(int*)malloc(Elements*sizeof(int));
PartSize[I]=0;
}
for(I=0;I<Elements;I++)
fscanf(InFile,"%d%d%d",&Element[I].Vertex[0],&Element[I].Vertex[1],&Element[I].Vertex[2]);
//读入单元的三个vertex
//构造PartE
for(J=0;J<Elements;J++)
{
fscanf(InFile,"%d",&I);
PartE[I][PartSize[I]++]=J;
}
fclose(InFile);
//关闭文件
for(I=0;I<PROCNO;I++)
{
NodeCounter[I]=0;
for(J=0;J<Nodes;J++)
{
Node[J].LocalNode=-1;
PartN[I][J]=0;
}//初始化
//构造PartN
for(J=0;J<PartSize[I];J++)
{
for(K=0;K<3;K++)
{
V=Element[PartE[I][J]].Vertex[K];
if(Node[V].LocalNode==-1)
Node[V].LocalNode=NodeCounter[I]++;
if(Node[V].GlobalDOF>-1&&PartN[I][V]==0)
{
Node[V].Type++;
PartN[I][V]=1;
}
}
}
}
for(I=0;I<PROCNO;I++)
{
if(I<10)
sprintf(FileName,"Data0%d.In",I);
else
sprintf(FileName,"Data%d.In",I);
OutFile=fopen(FileName,"w");
fprintf(OutFile," %d %d/n",NodeCounter[I],PartSize[I]);
NodeCounter[I]=0;
for(J=0;J<Nodes;J++)
Node[J].LocalNode=-1;
for(J=0;J<PartSize[I];J++)
{
for(K=0;K<3;K++)
{
V=Element[PartE[I][J]].Vertex[K];
if(Node[V].LocalNode==-1)
{
Node[V].LocalNode=NodeCounter[I]++;
fprintf(OutFile," %f %f %d/n",Node[V].Pos[0],Node[V].Pos[1],Node[V].Type);
}
}
}
for(J=0;J<PartSize[I];J++)
{
for(K=0;K<3;K++)
{
V=Element[PartE[I][J]].Vertex[K];
fprintf(OutFile," %d",Node[V].LocalNode);
}
fprintf(OutFile,"/n");
}
for(K=0;K<PROCNO;K++)
{
Common[K]=0;
if(I!=K)
for(J=0;J<Nodes;J++)
if(PartN[I][J]>0&&PartN[K][J]>0)
Common[K]++;
}
for(K=0;K<PROCNO;K++)
{
fprintf(OutFile," %d/n",Common[K]);
if(Common[K]>0)
{
for(J=0;J<Nodes;J++)
if(PartN[I][J]>0&&PartN[K][J]>0)
fprintf(OutFile," %d",Node[J].LocalNode);
fprintf(OutFile,"/n");
}
}
fclose(OutFile);
}
}
/* FemPar.c
Written by XiaoFei,college of mathematics science and computing technology,CSU,2009-5 */
#include<stdio.h>
#include<malloc.h>
#include"mpi.h"
#define PROCNO 4
typedef struct
{
float Pos[2];
int Local;
int Type;
}NodeType;
typedef struct
{
int Vertex[3];
}ElementType;
NodeType *Node;
ElementType *Element;
int *Shared,MaxCommon,Common[PROCNO],*Neighbours[PROCNO];
int ProcNo,ProcID,Nodes,Elements,IntNodes,IBNodes;
float *Buf;
float InnerProduct(float *A1,float *A2,float *B1,float *B2)
{
int I;
float IP=0.0,IPTocal;
for(I=0;I<IntNodes;I++)
IP+=A1[I]*B1[I];
for(I=0;I<IBNodes;I++)
IP+=(A2[I]*B2[I])/Shared[I];
MPI_Allreduce(&IP,&IPTocal,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD);
return(IPTocal);
}
void Update(float *A)
{
int I,J;
MPI_Status Status;
for(I=0;I<PROCNO;I++)
{
for(J=0;J<Common[I];J++)
Buf[J]=A[Node[Neighbours[I][J]].Local];
if(Common[I]>0)
MPI_Send(&Buf[0],Common[I],MPI_FLOAT,I,10,MPI_COMM_WORLD);
}
for(I=0;I<PROCNO;I++)
{
if(Common[I]>0)
MPI_Recv(&Buf[0],Common[I],MPI_FLOAT,I,10,MPI_COMM_WORLD,&Status);
for(J=0;J<Common[I];J++)
A[Node[Neighbours[I][J]].Local]+=Buf[J];
}
}
int CG(float **Ap,float **As,float **Bp,float *Fp,float *Fs,float *Vp,float *Vs)
{
float *Rp,*Rs,*Pp,*Ps,*Qp,*Qs,GammaOld,GammaNew,Tau,Alpha,Beta,Tol=1.0e-4;
int I,J,K,KMax=250;
Pp=(float*)malloc(IntNodes*sizeof(float));
Ps=(float*)malloc(IBNodes*sizeof(float));
Qp=(float*)malloc(IntNodes*sizeof(float));
Qs=(float*)malloc(IBNodes*sizeof(float));
Rp=(float*)malloc(IntNodes*sizeof(float));
Rs=(float*)malloc(IBNodes*sizeof(float));
Update(Fs);
for(I=0;I<IntNodes;I++)
Pp[I]=Rp[I]=Fp[I];
for(I=0;I<IBNodes;I++)
Ps[I]=Rs[I]=Fs[I];
GammaNew=InnerProduct(Rp,Rs,Rp,Rs);
if(GammaNew<Tol*Tol)
return(1);
if(ProcID==0)
printf("Gamma = %f/n",GammaNew);
for(K=0;K<KMax;K++)
{
for(I=0;I<IntNodes;I++)
{
for(J=0,Qp[I]=0.0;J<IntNodes;J++)
Qp[I]+=Ap[I][J]*Pp[J];
for(J=0;J<IBNodes;J++)
Qp[I]+=Bp[I][J]*Ps[J];
}
for(I=0;I<IBNodes;I++)
{
for(J=0,Qs[I]=0.0;J<IntNodes;J++)
Qs[I]+=Bp[I][J]*Pp[J];
for(J=0;J<IBNodes;J++)
Qs[I]+=As[I][J]*Ps[J];
}
Update(Qs);
Tau=InnerProduct(Pp,Ps,Qp,Qs);
Alpha=GammaNew/Tau;
for(I=0;I<IBNodes;I++)
{
Vp[I]+=Alpha*Pp[I];
Rp[I]-=Alpha*Qp[I];
}
for(I=0;I<IBNodes;I++)
{
Vs[I]+=Alpha*Ps[I];
Rs[I]-=Alpha*Qs[I];
}
GammaOld=GammaNew;
GammaNew=InnerProduct(Rp,Rs,Rp,Rs);
if(ProcID==0)
printf("Gamma = %f (K = %d)/n",GammaNew,K);
if(GammaNew<Tol*Tol)
return(1);
Beta=GammaNew/GammaOld;
for(I=0;I<IntNodes;I++)
Pp[I]=Rp[I]+Beta*Pp[I];
for(I=0;I<IBNodes;I++)
Ps[I]=Rs[I]+Beta*Ps[I];
}
return(0);
}
float BC(float X,float Y)
{
return(X+Y);
}
main(int argc,char** argv)
{
FILE *InFile,*OutFile;
char FileName[40];
int I,J,K,II,JJ;
float **Ap,**Bp,**As,*Fp,*Fs,*Vp,*Vs;
float SLoc[3][2],TwoA,Area,Gr0[3],Gr1[3],StiffJI;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&ProcID);
MPI_Comm_size(MPI_COMM_WORLD,&ProcNo);
if(ProcNo!=PROCNO)
{
printf("Unexpected number of processors./n");
MPI_Abort(MPI_COMM_WORLD,-1);
}
if(ProcID<10)
sprintf(FileName,"Data0%d.In",ProcID);
else
sprintf(FileName,"Data%d.In",ProcID);
InFile=fopen(FileName,"r");
fscanf(InFile,"%d%d",&Nodes,&Elements);
Node=(NodeType*)malloc(Nodes*sizeof(NodeType));
for(I=0,IntNodes=0,IBNodes=0;I<Nodes;I++)
{
fscanf(InFile,"%f%f%d",&Node[I].Pos[0],&Node[I].Pos[1],&Node[I].Type);
if(Node[I].Type==1)
Node[I].Local=IntNodes++;
else if(Node[I].Type>1)
Node[I].Local=IBNodes++;
else
Node[I].Local=-1;
}
Shared=(int*)malloc(IBNodes*sizeof(int));
for(I=0,IBNodes=0;I<Nodes;I++)
if(Node[I].Type>1)
Shared[IBNodes++]=Node[I].Type;
Element=(ElementType*)malloc(Elements*sizeof(ElementType));
for(I=0;I<Elements;I++)
fscanf(InFile,"%d%d%d",&Element[I].Vertex[0],&Element[I].Vertex[1],&Element[I].Vertex[2]);
MaxCommon=0;
for(I=0;I<PROCNO;I++)
{
fscanf(InFile,"%d",&Common[I]);
if(Common[I]>MaxCommon)
MaxCommon=Common[I];
if(Common[I]>0)
Neighbours[I]=(int*)malloc(Common[I]*sizeof(int));
for(J=0;J<Common[I];J++)
fscanf(InFile,"%d",&Neighbours[I][J]);
}
Buf=(float*)malloc(MaxCommon*sizeof(float));
fclose(InFile);
printf("ProcID = %d,IntNodes = %d,IBNodes = %d/n",ProcID,IntNodes,IBNodes);
Ap=(float**)calloc(IntNodes,sizeof(float*));
for(I=0;I<IntNodes;I++)
Ap[I]=(float*)calloc(IntNodes,sizeof(float));
Bp=(float**)calloc(IBNodes,sizeof(float*));
for(I=0;I<IntNodes;I++)
Bp[I]=(float*)calloc(IntNodes,sizeof(float));
As=(float**)calloc(IBNodes,sizeof(float*));
for(I=0;I<IBNodes;I++)
As[I]=(float*)calloc(IBNodes,sizeof(float));
Fp=(float*)calloc(IntNodes,sizeof(float));
Fs=(float*)calloc(IBNodes,sizeof(float));
Vp=(float*)calloc(IntNodes,sizeof(float));
Vs=(float*)calloc(IBNodes,sizeof(float));
for(K=0;K<Elements;K++)
{
SLoc[0][0]=Node[Element[K].Vertex[0]].Pos[0];
SLoc[1][0]=Node[Element[K].Vertex[1]].Pos[0];
SLoc[2][0]=Node[Element[K].Vertex[2]].Pos[0];
SLoc[0][1]=Node[Element[K].Vertex[0]].Pos[1];
SLoc[1][1]=Node[Element[K].Vertex[1]].Pos[1];
SLoc[2][1]=Node[Element[K].Vertex[2]].Pos[1];
TwoA=SLoc[0][0]*(SLoc[1][1]-SLoc[2][1])+
SLoc[1][0]*(SLoc[2][1]-SLoc[0][1])+
SLoc[2][0]*(SLoc[0][1]-SLoc[1][1]);
Area=0.5*TwoA;
Gr0[0]=(SLoc[1][1]-SLoc[2][1])/TwoA;
Gr0[1]=(SLoc[2][1]-SLoc[0][1])/TwoA;
Gr0[2]=(SLoc[0][1]-SLoc[1][1])/TwoA;
Gr0[0]=-(SLoc[1][0]-SLoc[2][0])/TwoA;
Gr0[1]=-(SLoc[2][0]-SLoc[0][0])/TwoA;
Gr0[2]=-(SLoc[0][0]-SLoc[1][0])/TwoA;
for(J=0;J<3;J++)
{
JJ=Element[K].Vertex[J];
if(Node[JJ].Type==1)
for(I=0;I<3;I++)
{
II=Element[K].Vertex[I];
StiffJI=Area*(Gr0[I]*Gr0[J]+Gr1[I]*Gr1[J]);
if(Node[II].Type==1)
Ap[Node[JJ].Local][Node[II].Local]+=StiffJI;
else
if(Node[II].Type>1)
Bp[Node[JJ].Local][Node[II].Local]+=StiffJI;
else
if(Node[II].Type==0)
Fp[Node[JJ].Local]-=BC(Node[II].Pos[0],Node[II].Pos[1])*StiffJI;
}
else
if(Node[JJ].Type>1)
for(I=0;I<3;I++)
{
II=Element[K].Vertex[I];
StiffJI=Area*(Gr0[I]*Gr0[J]+Gr1[I]*Gr1[J]);
if(Node[II].Type>1)
As[Node[JJ].Local][Node[II].Local]+=StiffJI;
else
if(Node[JJ].Type==0)
Fs[Node[JJ].Local]-=BC(Node[II].Pos[0],Node[II].Pos[1])*StiffJI;
}
}
}
CG(Ap,As,Bp,Fp,Fs,Vp,Vs);
for(I=0;I<Nodes;I++)
if(Node[I].Type==1)
printf(" %f %f %f/n",Node[I].Pos[0],Node[I].Pos[1],Vp[Node[I].Local]);
else
if(Node[I].Type>1)
printf(" %f %f %f/n",Node[I].Pos[0],Node[I].Pos[1],Vs[Node[I].Local]);
MPI_Finalize();
}
附录B 任务分配预处理程序
#include<stdio.h>
#define FILENAME "mesh.txt"
#define PROCNO 4
typedef struct{
float Pos[2]; //位置坐标
int GlobalDOF;
int LocalNode;
int Type;
}NodeType;
typedef struct{
int Vertex[3];
}ElementType;
NodeType* Node;
ElementType* Element;
int PartSize[PROCNO],*PartE[PROCNO],*PartN[PROCNO];
main(int argc,char** argv)
{
FILE *InFile,*OutFile;
int Nodes,Elements,I,J,K,V,NodeCounter[PROCNO],Common[PROCNO];
char FileName[40];
InFile=fopen(FILENAME,"r");
//读入节点信息
fscanf(InFile,"%d",&Nodes);//节点数目
Node=(NodeType*)malloc(Nodes*sizeof(NodeType));
for(I=0;I<PROCNO;I++)
PartN[I]=(int*)malloc(Nodes*sizeof(int));
for(I=0;I<Nodes;I++)
{
fscanf(InFile,"%d%f%f",&Node[I].GlobalDOF,&Node[I].Pos[0],&Node[I].Pos[1]);
//读入节点GlobalDOF,坐标,
Node[I].Type=0;
//初始化节点符号,<0表示边界
}
//读入单元信息
fscanf(InFile,"%d",&Elements); //单元数目
Element=(ElementType*)malloc(Elements*sizeof(ElementType));
for(I=0;I<PROCNO;I++)
{
PartE[I]=(int*)malloc(Elements*sizeof(int));
PartSize[I]=0;
}
for(I=0;I<Elements;I++)
fscanf(InFile,"%d%d%d",&Element[I].Vertex[0],&Element[I].Vertex[1],&Element[I].Vertex[2]);
//读入单元的三个vertex
//构造PartE
for(J=0;J<Elements;J++)
{
fscanf(InFile,"%d",&I);
PartE[I][PartSize[I]++]=J;
}
fclose(InFile);
//关闭文件
for(I=0;I<PROCNO;I++)
{
NodeCounter[I]=0;
for(J=0;J<Nodes;J++)
{
Node[J].LocalNode=-1;
PartN[I][J]=0;
}//初始化
//构造PartN
for(J=0;J<PartSize[I];J++)
{
for(K=0;K<3;K++)
{
V=Element[PartE[I][J]].Vertex[K];
if(Node[V].LocalNode==-1)
Node[V].LocalNode=NodeCounter[I]++;
if(Node[V].GlobalDOF>-1&&PartN[I][V]==0)
{
Node[V].Type++;
PartN[I][V]=1;
}
}
}
}
for(I=0;I<PROCNO;I++)
{
if(I<10)
sprintf(FileName,"Data0%d.In",I);
else
sprintf(FileName,"Data%d.In",I);
OutFile=fopen(FileName,"w");
fprintf(OutFile," %d %d/n",NodeCounter[I],PartSize[I]);
NodeCounter[I]=0;
for(J=0;J<Nodes;J++)
Node[J].LocalNode=-1;
for(J=0;J<PartSize[I];J++)
{
for(K=0;K<3;K++)
{
V=Element[PartE[I][J]].Vertex[K];
if(Node[V].LocalNode==-1)
{
Node[V].LocalNode=NodeCounter[I]++;
fprintf(OutFile," %f %f %d/n",Node[V].Pos[0],Node[V].Pos[1],Node[V].Type);
}
}
}
for(J=0;J<PartSize[I];J++)
{
for(K=0;K<3;K++)
{
V=Element[PartE[I][J]].Vertex[K];
fprintf(OutFile," %d",Node[V].LocalNode);
}
fprintf(OutFile,"/n");
}
for(K=0;K<PROCNO;K++)
{
Common[K]=0;
if(I!=K)
for(J=0;J<Nodes;J++)
if(PartN[I][J]>0&&PartN[K][J]>0)
Common[K]++;
}
for(K=0;K<PROCNO;K++)
{
fprintf(OutFile," %d/n",Common[K]);
if(Common[K]>0)
{
for(J=0;J<Nodes;J++)
if(PartN[I][J]>0&&PartN[K][J]>0)
fprintf(OutFile," %d",Node[J].LocalNode);
fprintf(OutFile,"/n");
}
}
fclose(OutFile);
}
}
相关文章推荐
- 基于有限元方法的弹簧系统位移求解
- PDE2D--用Fortran编译器的跨平台的通用性颇佳的基于有限元方法的微分方程(组)求解器
- 双二次Lagrange 有限元计算特征值程序(基于iFEM)
- vs2012-vs2013编译出来的程序不能在xp上运行解决方法
- 微信小程序基于slider组件动态修改标签透明度的方法示例
- 基于OpenCV的程序脱离动态链接库运行方法
- 不使用WxSmith和WxFormBuilder生成界面,手工输写基于WxWidgets程序的配置方法
- 基于OpenCV的程序脱离动态链接库运行方法
- java开发第二个jni示例程序(基于linux操作系统)--native层调用java方法
- 程序启动时,隐藏对话框的方法(基于vc的对话框工程)
- 求解求最大公约数定义的算法,这个程序求不出来,网上百度的算法不对?
- 基于历史K线数据比较的量化选股方法及其系统分享(第2章 C主程序---关键数据结构)
- VC#.NET下基于WinForm的系统登录程序解决方法
- 约瑟夫问题的笨方法求解程序
- Python基于辗转相除法求解最大公约数的方法示例
- 基于spark运行scala程序(sbt和命令行方法)
- 基于 OpenCV 的程序脱离动态链接库运行方法
- 13种提升基于MVVM模式的WP7程序性能的方法(转)
- 基于统计方法的二字词发掘程序(改进)
- C++:基于LL(1)方法的语法分析程序-3