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

📄 parpoi.cpp

📁 pic 模拟程序!面向对象
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#ifdef PETSC#define MPICH_SKIP_MPICXXextern "C" {#include "mpi.h"}#include "parpoi.h"#include "grid.h"extern MPI_Comm XOOPIC_COMM;extern int *GlobalArgc;extern char ***GlobalArgv;#define DEBUGParallelPoisson::ParallelPoisson(Scalar **_epsi, Grid *_grid) {  epsi = _epsi;  grid=_grid;  Viewer viewer;  Viewer aviewer;  Viewer maviewer;  int nPoints = (grid->getJ() +1) * (grid->getK() +1);  int debug=0;  int ierr;#ifdef DEBUG  int size;  double foo=5;  debug = 1;#endif  // create the mpiPhi vector.  //  all the petsc stuff returns an error.    if(debug) printf("\n Calling petsc initialize\n");//  CHKERRA( PetscInitialize(GlobalArgc,GlobalArgv,(char *)0,"RTFM") ); // ierr=PetscInitialize(GlobalArgc,GlobalArgv,(char *)0,"RTFM");  CHKERRA(ierr);/*  if(debug) printf("\n MPI_COMM_WORLD: %d\n",MPI_COMM_WORLD);    if(debug) printf("\n PETSC_COMM_WORLD: %d\n",PETSC_COMM_WORLD);    if(debug) MPI_Comm_size(PETSC_COMM_WORLD,&size);   if(debug) printf("\n size: %d\n",size);    if(debug) printf("\n VecCreateMPI\n"); *///  ierr = ViewerDrawOpen(PETSC_COMM_WORLD,PETSC_NULL,PETSC_NULL,0,0,1500,900,//                         &viewer); CHKERRA(ierr);  ierr= ViewerASCIIOpen(PETSC_COMM_WORLD,"asciiviewer",&aviewer);  CHKERRA(ierr);  ierr= ViewerASCIIOpen(PETSC_COMM_WORLD,"mpiCoeff.txt",&maviewer);  CHKERRA(ierr);  ierr= VecCreateMPI(PETSC_COMM_WORLD, nPoints,PETSC_DECIDE, &mpiPhi) ;  CHKERRA(ierr);  ierr= VecCreateMPI(PETSC_COMM_WORLD, nPoints,PETSC_DECIDE, &mpiRho) ;  CHKERRA(ierr);   ierr=VecCreateMPI(PETSC_COMM_WORLD, nPoints,PETSC_DECIDE, &mpiepsi);  CHKERRA(ierr);  ierr=VecCreateMPI(PETSC_COMM_WORLD, nPoints,PETSC_DECIDE, &mpiNumbering);  CHKERRA(ierr);  if(debug) printf("\n MatrCreateMPI\n");  ierr= MatCreateMPIAIJ(PETSC_COMM_WORLD, nPoints,nPoints,PETSC_DECIDE,									PETSC_DECIDE,5,PETSC_NULL,2,PETSC_NULL,&mpiCoef);  CHKERRA(ierr);  int j,k;  // set up the default coefficients.  for(k=0;k<=grid->getK();k++) 	  for(j=0;j<=grid->getJ();j++) {		double tmp = epsi[MIN(j,grid->getJ()-1)][MIN(k,grid->getK()-1)];		BCTypes type;		Boundary *B =  grid->GetNodeBoundary()[j][k];		if(B!=NULL) type = B->getBCType();		else type = FREESPACE;    try{		  set_coefficient(j,k,type,grid);    }    catch(Oops& oops2){      oops2.prepend("ParallelPoisson::ParallelPoisson: Error: \n");//done      throw oops2;    }		PetscVecSetValue(mpiepsi,grid->getGlobalIndex(j,k,HERE),tmp,INSERT_VALUES);		PetscVecSetValue(mpiNumbering,grid->getGlobalIndex(j,k,HERE),							  (double) grid->getGlobalIndex(j,k,HERE), INSERT_VALUES);	}  if(debug) printf("\n VecAssemble\n");  ierr=VecAssemblyBegin(mpiepsi);  CHKERRA(ierr);  ierr=VecAssemblyBegin(mpiPhi);  CHKERRA(ierr);  ierr=VecAssemblyBegin(mpiRho);  CHKERRA(ierr);  ierr=VecAssemblyEnd(mpiepsi);  CHKERRA(ierr);  ierr=VecAssemblyEnd(mpiNumbering);  CHKERRA(ierr);  ierr=VecAssemblyEnd(mpiPhi);  CHKERRA(ierr);  ierr=(VecAssemblyEnd(mpiRho));  CHKERRA(ierr);  ierr = ViewerPushFormat(aviewer,VIEWER_FORMAT_ASCII_INDEX,"Tabulation");CHKERRA(ierr);  ierr = VecView(mpiepsi,aviewer); CHKERRA(ierr);  ierr = VecView(mpiNumbering, aviewer); CHKERRA(ierr);  ierr=MatAssemblyBegin(mpiCoef,MAT_FINAL_ASSEMBLY);  CHKERRA(ierr);  ierr=MatAssemblyEnd(mpiCoef,MAT_FINAL_ASSEMBLY);  CHKERRA(ierr);  ierr = ViewerPushFormat(maviewer,VIEWER_FORMAT_ASCII_MATLAB, "Matrix");  CHKERRA(ierr);   ierr = MatView(mpiCoef,maviewer);  CHKERRA(ierr);  ierr=(SLESCreate(PETSC_COMM_WORLD, &petsc_solver));  CHKERRA(ierr);  ierr=(SLESSetOperators(petsc_solver,mpiCoef,mpiCoef,SAME_PRECONDITIONER));  CHKERRA(ierr);  SLESSetFromOptions(petsc_solver);  //SLESPrintHelp(petsc_solver);}// switches to the appropraite set_coefficient subfunction based on// the grid geometry.void ParallelPoisson::set_coefficient(int j,int k, BCTypes type, Grid *grid)   throw(Oops){	switch (grid->query_geometry()) {	 case ZRGEOM:		 set_coefficient_rz( j,  k, type, grid);		 break;	  case ZXGEOM:      try{		    set_coefficient_xy( j,  k, type, grid);      }      catch(Oops& oops){        oops.prepend("ParallelPoisson::set_coefficient: Error:\n"); //ParallelPoisson::ParallelPoisson        throw oops;      }		  break;	 };}// Set the matrix coefficients to reflect the local epsilon and// boundary conditions, for XY geometry.void ParallelPoisson::set_coefficient_xy(int j, int k, BCTypes type, Grid *grid)   throw(Oops){  Vector2 **X=grid->getX();  int J=grid->getJ();  int K=grid->getK();  int Iup,Idown,Ileft,Iright,Icenter;  //  global indices...  Iup = grid->getGlobalIndex(j,k,UP);  Idown = grid->getGlobalIndex(j,k,DOWN);  Ileft = grid->getGlobalIndex(j,k,LEFT);  Iright = grid->getGlobalIndex(j,k,RIGHT);  Icenter = grid->getGlobalIndex(j,k,HERE);  if(type == PERIODIC_BOUNDARY)  { //need to diddle the indices a bit	  Iup = grid->getGlobalIndex(j,k,UPWRAP);	  Idown = grid->getGlobalIndex(j,k,DOWNWRAP);	  Ileft = grid->getGlobalIndex(j,k,LEFTWRAP);	  Iright = grid->getGlobalIndex(j,k,RIGHTWRAP);	  //Icenter handled already.  }    Scalar dxa = X[j][k].e1()  -X[MAX(0,j-1)][k].e1(); // dx-  Scalar dxb = X[MIN(J,j+1)][k].e1()-X[j][k].e1();  // dx+  Scalar dxave= 0.5*(dxa + dxb);  //dx  Scalar dya = X[j][k].e2()-X[j][MAX(0,k-1)].e2();  //dy-  Scalar dyb = X[j][MIN(K,k+1)].e2() - X[j][k].e2();  //dy+  Scalar dyave = 0.5 * (dya + dyb); //dy	// epsilon coefficients, weighted appropriately for each cell side	Scalar e1a,e1b,e2a,e2b;//	e1a = (epsi[i][j]*dya + epsi[i][MIN(J,j+1)]*dyb)/(dya + dyb);//	e1b = (epsi[MIN(i+1,I)][j]*dya + epsi[MIN(i+1,I)][MIN(J,j+1)]*dyb)/(dya + dyb);//	e2a = (epsi[i][j]*dxa + epsi[MIN(I,i+1)][j]*dxa)/(dxa + dxb);//	e2b = (epsi[i][MIN(j+1,J)]*dxa + epsi[MIN(i+1,I)][MIN(J,j+1)]*dxb)/(dxa + dxb);  int jm = MAX(j-1,0);  int km = MAX(k-1,0);  e1a = (epsi[jm][km]*dya + epsi[jm][MIN(k,K-1)]*dyb)/(dya + dyb);  e1b = (epsi[MIN(j,J-1)][km]*dya + epsi[MIN(j,J-1)][MIN(k,K-1)]*dyb)/(dya + dyb);  e2a = (epsi[jm][km]*dxa + epsi[MIN(j,J-1)][km]*dxb)/(dxa + dxb);  e2b = (epsi[jm][MIN(k,K-1)]*dxa + epsi[MIN(j,J-1)][MIN(k,K-1)]*dxb)/(dxa + dxb);  Scalar upc,downc,rightc,leftc,centerc;  //  the coefficients for the stencil.    // The next block of code sets stuff up appropriately if   // we're at the edge of the system and it is a SPATIAL_REGION_BOUNDARY  // Need to do some special things at spatial region boundaries!  // we just correct some things which weren't right for the   // normal FREESPACE or DIELECTRIC  if(j==0 && Ileft != -1) { // we're on the left hand side	  dxave=dxa=dxb;  // uniform mesh assumption.  }  if(j==J && Iright != -1) { // we're on the righthand side	  dxave=dxb=dxa;  // uniform mesh assumption.  }  if(k==0 && Iup != -1) { // we're on the top side	  dyave=dya=dyb;  // uniform mesh assumption.  }  if(k==K && Idown != -1) { // we're on the top side	  dyave=dyb=dya;  // uniform mesh assumption.  }    switch(type) 	  {		 		case SPATIAL_REGION_BOUNDARY:		case PERIODIC_BOUNDARY:  		case FREESPACE:			{				centerc = upc = downc = leftc = rightc = 0;				if(Iup >=0) { /* valid index */					upc = e2a/(dyave*dya);				}				if(Idown >=0) { /* valid index */					downc = e2b/(dyave*dyb);				}				if(Ileft >=0) { /* valid index */					leftc = e1a/(dxa * dxave);				}				if(Iright >=0) { /* valid index */					rightc = e1b/(dxb * dxave);				}				centerc = -( upc + downc + leftc + rightc );				break;			}   //case FREESPACE		case CONDUCTING_BOUNDARY:			{				upc=downc=leftc=rightc=0;				centerc = 1;				break;			}		 case DIELECTRIC_BOUNDARY:			 {				 centerc = upc = downc = leftc = rightc = 0;				 if(j==0 && Ileft == -1) { // left hand wall neumann					 leftc = 0;					 rightc = 2 * e1b / (dxb * dxb);					 centerc -= rightc;					 }	 else						 if(j==J && Iright == -1) { // right hand wall neumann						 rightc = 0;						 leftc = 2 * e1a / (dxa * dxa);						 centerc -= leftc;					 } else {  // dielectric in the center of the system:  normal coeff.						 leftc = e1a / (dxa * dxave);						 rightc = e1b/(dxb * dxave);						 centerc -= leftc + rightc;					 }				 if(k==0 && Iup == -1) { //top wall neumann					 upc = 0;					 downc = 2 * e2b / (dyb * dyb);					 centerc -= downc;				 } else					 if(k==K && Idown == -1) { //bottom wall neumann						 downc = 0;						 upc = 2 * e2a / (dya * dya);						 centerc -= upc;					 } else {// dielectric in the center of the system:  normal coeff.						 upc = e2a/(dyave*dya);						 downc = e2b/(dyave*dyb);						 centerc -= upc + downc;					 }				 break;			 }  // case DIELECTRIC_BOUNDARY		 case CYLINDRICAL_AXIS:			 {         stringstream ss (stringstream::in | stringstream::out);         ss <<"ParallelPoisson::set_coefficient_xy: Error: \n"<<           "Can't have a cylindrical axis in xy-geometry!\n" << endl;				 std::string msg;         ss >> msg;         Oops oops(msg);         throw oops;    // exit()  ParallelPoisson::set_coefficient:				 break;			 }		 default: 			 {				 cout << "Error, unhandled boundary type in ParallelPoisson-xy\n" << endl;				 break;			 }	 };  // All cases have to set up their coefficients.  PetscMatSetValue(mpiCoef,Icenter,Icenter,centerc,INSERT_VALUES);  if(Iup >=0) { /* valid index */	  PetscMatSetValue(mpiCoef,Icenter,Iup,upc,INSERT_VALUES);  }

⌨️ 快捷键说明

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