static char help[] ="Tests sequential and parallel MatMatMatMult() and MatPtAP(). Modified from ex96.c \n\ -Mx , where = number of coarse grid points in the x-direction\n\ -My , where = number of coarse grid points in the y-direction\n\ -Mz , where = number of coarse grid points in the z-direction\n\ -Npx , where = number of processors in the x-direction\n\ -Npy , where = number of processors in the y-direction\n\ -Npz , where = number of processors in the z-direction\n\n"; /* Example of usage: mpiexec -n 3 ./ex41 -Mx 10 -My 10 -Mz 10 */ #include #include /* User-defined application contexts */ typedef struct { PetscInt mx,my,mz; /* number grid points in x, y and z direction */ Vec localX,localF; /* local vectors with ghost region */ DM da; Vec x,b,r; /* global vectors */ Mat J; /* Jacobian on grid */ } GridCtx; typedef struct { GridCtx fine; GridCtx coarse; PetscInt ratio; Mat Ii; /* interpolation from coarse to fine */ } AppCtx; #define COARSE_LEVEL 0 #define FINE_LEVEL 1 /* Mm_ratio - ration of grid lines between fine and coarse grids. */ int main(int argc,char **argv) { AppCtx user; PetscMPIInt size,rank; PetscInt m,n,M,N,i,nrows; PetscScalar one = 1.0; PetscReal fill=2.0; Mat A,P,R,C,PtAP,D; PetscScalar *array; PetscRandom rdm; PetscBool Test_3D=PETSC_FALSE,flg; const PetscInt *ia,*ja; PetscCall(PetscInitialize(&argc,&argv,NULL,help)); PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size)); PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); /* Get size of fine grids and coarse grids */ user.ratio = 2; user.coarse.mx = 4; user.coarse.my = 4; user.coarse.mz = 4; PetscCall(PetscOptionsGetInt(NULL,NULL,"-Mx",&user.coarse.mx,NULL)); PetscCall(PetscOptionsGetInt(NULL,NULL,"-My",&user.coarse.my,NULL)); PetscCall(PetscOptionsGetInt(NULL,NULL,"-Mz",&user.coarse.mz,NULL)); PetscCall(PetscOptionsGetInt(NULL,NULL,"-ratio",&user.ratio,NULL)); if (user.coarse.mz) Test_3D = PETSC_TRUE; user.fine.mx = user.ratio*(user.coarse.mx-1)+1; user.fine.my = user.ratio*(user.coarse.my-1)+1; user.fine.mz = user.ratio*(user.coarse.mz-1)+1; if (rank == 0) { if (!Test_3D) { PetscCall(PetscPrintf(PETSC_COMM_SELF,"coarse grids: %" PetscInt_FMT " %" PetscInt_FMT "; fine grids: %" PetscInt_FMT " %" PetscInt_FMT "\n",user.coarse.mx,user.coarse.my,user.fine.mx,user.fine.my)); } else { PetscCall(PetscPrintf(PETSC_COMM_SELF,"coarse grids: %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "; fine grids: %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",user.coarse.mx,user.coarse.my,user.coarse.mz,user.fine.mx,user.fine.my,user.fine.mz)); } } /* Set up distributed array for fine grid */ if (!Test_3D) { PetscCall(DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,user.fine.mx,user.fine.my,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&user.fine.da)); } else { PetscCall(DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,user.fine.mx,user.fine.my,user.fine.mz,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE, 1,1,NULL,NULL,NULL,&user.fine.da)); } PetscCall(DMSetFromOptions(user.fine.da)); PetscCall(DMSetUp(user.fine.da)); /* Create and set A at fine grids */ PetscCall(DMSetMatType(user.fine.da,MATAIJ)); PetscCall(DMCreateMatrix(user.fine.da,&A)); PetscCall(MatGetLocalSize(A,&m,&n)); PetscCall(MatGetSize(A,&M,&N)); /* set val=one to A (replace with random values!) */ PetscCall(PetscRandomCreate(PETSC_COMM_WORLD,&rdm)); PetscCall(PetscRandomSetFromOptions(rdm)); if (size == 1) { PetscCall(MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg)); if (flg) { PetscCall(MatSeqAIJGetArray(A,&array)); for (i=0; i