int main(int argc,char **argv) { PetscMPIInt rank; PetscInt M=8,dof=1,stencil_width=1,i,start,end,P=5,N = 6,m=PETSC_DECIDE,n=PETSC_DECIDE,p=PETSC_DECIDE,pt = 0,st = 0; PetscErrorCode ierr; PetscBool flg = PETSC_FALSE,flg2,flg3; DMBoundaryType periodic; DMDAStencilType stencil_type; DM da; Vec local,global,local_copy; PetscScalar value; PetscReal norm,work; PetscViewer viewer; char filename[64]; FILE *file; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-dof",&dof,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-stencil_width",&stencil_width,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-periodic",&pt,NULL);CHKERRQ(ierr); periodic = (DMBoundaryType) pt; ierr = PetscOptionsGetInt(NULL,NULL,"-stencil_type",&st,NULL);CHKERRQ(ierr); stencil_type = (DMDAStencilType) st; ierr = PetscOptionsHasName(NULL,NULL,"-grid2d",&flg2);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL,"-grid3d",&flg3);CHKERRQ(ierr); if (flg2) { ierr = DMDACreate2d(PETSC_COMM_WORLD,periodic,periodic,stencil_type,M,N,m,n,dof,stencil_width,NULL,NULL,&da);CHKERRQ(ierr); } else if (flg3) { ierr = DMDACreate3d(PETSC_COMM_WORLD,periodic,periodic,periodic,stencil_type,M,N,P,m,n,p,dof,stencil_width,NULL,NULL,NULL,&da);CHKERRQ(ierr); } else { ierr = DMDACreate1d(PETSC_COMM_WORLD,periodic,M,dof,stencil_width,NULL,&da);CHKERRQ(ierr); } ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr); ierr = VecDuplicate(local,&local_copy);CHKERRQ(ierr); /* zero out vectors so that ghostpoints are zero */ value = 0; ierr = VecSet(local,value);CHKERRQ(ierr); ierr = VecSet(local_copy,value);CHKERRQ(ierr); ierr = VecGetOwnershipRange(global,&start,&end);CHKERRQ(ierr); for (i=start; i<end; i++) { value = i + 1; ierr = VecSetValues(global,1,&i,&value,INSERT_VALUES);CHKERRQ(ierr); } ierr = VecAssemblyBegin(global);CHKERRQ(ierr); ierr = VecAssemblyEnd(global);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMLocalToLocalBegin(da,local,INSERT_VALUES,local_copy);CHKERRQ(ierr); ierr = DMLocalToLocalEnd(da,local,INSERT_VALUES,local_copy);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-save",&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); sprintf(filename,"local.%d",rank); ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIGetPointer(viewer,&file);CHKERRQ(ierr); ierr = VecView(local,viewer);CHKERRQ(ierr); fprintf(file,"Vector with correct ghost points\n"); ierr = VecView(local_copy,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = VecAXPY(local_copy,-1.0,local);CHKERRQ(ierr); ierr = VecNorm(local_copy,NORM_MAX,&work);CHKERRQ(ierr); ierr = MPI_Allreduce(&work,&norm,1,MPIU_REAL,MPIU_MAX,PETSC_COMM_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of difference %g should be zero\n",(double)norm);CHKERRQ(ierr); ierr = VecDestroy(&local_copy);CHKERRQ(ierr); ierr = VecDestroy(&local);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInitialize(&argc,&argv,(char*)0,help); const int d = 2; // d = DOF Mat A, Aminus; // these are dense d x d sequential matrices, unrelated to the grid // (each processor owns whole matrix) ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,d,d,d,NULL,&A); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(A,"A_"); CHKERRQ(ierr); ierr = MatSetFromOptions(A); CHKERRQ(ierr); // fill A double val[d][d], c = 3.0; val[0][0] = 0.0; val[0][1] = c; val[1][0] = c; val[1][1] = 0.0; ierr = fillsmallmat(2,val,A); CHKERRQ(ierr); // fill Aminus; see getAminus.m for computation of Aminus from A ierr = MatDuplicate(A,MAT_SHARE_NONZERO_PATTERN,&Aminus); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(Aminus,"Aminus_"); CHKERRQ(ierr); val[0][0] = -1.5; val[0][1] = 1.5; val[1][0] = 1.5; val[1][1] = -1.5; ierr = fillsmallmat(2,val,Aminus); CHKERRQ(ierr); // set up the grid DM da; ierr = DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, -50, // override with -da_grid_x or -da_refine d, 1, NULL, // dof = 1 and stencil width = 1 &da); CHKERRQ(ierr); // determine grid locations (cell-centered grid) DMDALocalInfo info; double L = 10.0, dx; ierr = DMDAGetLocalInfo(da,&info); CHKERRQ(ierr); dx = L / (double)(info.mx); ierr = DMDASetUniformCoordinates(da,dx/2,L-dx/2,-1.0,-1.0,-1.0,-1.0);CHKERRQ(ierr); // u = u(t_n), unew = u(t_n+1) Vec u, unew, F; ierr = DMCreateLocalVector(da,&u);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)u,"solution u"); CHKERRQ(ierr); ierr = VecDuplicate(u,&F);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)F,"flux F"); CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&unew);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)unew,"updated solution unew"); CHKERRQ(ierr); ierr = VecSet(unew,0.0); CHKERRQ(ierr); // at each cell we will need to compute Fcell = A qleft + Aminus dq Vec dq, qleft, tmp, Fcell; ierr = VecCreateSeq(PETSC_COMM_WORLD,d,&dq); CHKERRQ(ierr); ierr = VecDuplicate(dq,&qleft); CHKERRQ(ierr); ierr = VecDuplicate(dq,&tmp); CHKERRQ(ierr); ierr = VecDuplicate(dq,&Fcell); CHKERRQ(ierr); // view the solution graphically; control with -draw_pause PetscViewer viewer; ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,NULL,"solution u", PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,&viewer); CHKERRQ(ierr); /* time-stepping loop */ double t = 0.0, tf = 10.0, dt, nu; int n, NN = 10; dt = tf / NN; nu = dt / dx; for (n = 0; n < NN; ++n) { ierr = PetscPrintf(PETSC_COMM_WORLD, " time[%3d]=%6g: \n", n, t); CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,unew,INSERT_VALUES,u); CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,unew,INSERT_VALUES,u); CHKERRQ(ierr); ierr = VecView(u,viewer); CHKERRQ(ierr); double **au, **aunew, **aF; int j, p; ierr = DMDAVecGetArrayDOF(da, u, &au);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da, F, &aF);CHKERRQ(ierr); for (j=info.xs; j<info.xs+info.xm; j++) { double *adq, *aqleft, *aFcell; ierr = VecGetArray(dq,&adq); CHKERRQ(ierr); ierr = VecGetArray(qleft,&aqleft); CHKERRQ(ierr); for (p = 0; p < d; p++) { adq[p] = au[j+1][p] - au[j][p]; aqleft[p] = au[j][p]; } ierr = VecRestoreArray(dq,&adq); CHKERRQ(ierr); ierr = VecRestoreArray(qleft,&aqleft); CHKERRQ(ierr); // tmp = A qleft // Fcell = tmp + Aminus dq ierr = MatMult(A,qleft,tmp); CHKERRQ(ierr); ierr = MatMultAdd(Aminus,dq,tmp,Fcell); CHKERRQ(ierr); ierr = VecGetArray(Fcell,&aFcell); CHKERRQ(ierr); for (p = 0; p < d; p++) aF[j][p] = aFcell[p]; ierr = VecRestoreArray(Fcell,&aFcell); CHKERRQ(ierr); } ierr = DMDAVecRestoreArrayDOF(da, F, &aF);CHKERRQ(ierr); ierr = DMLocalToLocalBegin(da,F,INSERT_VALUES,F); CHKERRQ(ierr); ierr = DMLocalToLocalEnd(da,F,INSERT_VALUES,F); CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da, F, &aF);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da, unew, &aunew);CHKERRQ(ierr); for (j=info.xs; j<info.xs+info.xm; j++) { for (p = 0; p < d; p++) aunew[j][p] = au[j][p] - nu * (aF[j+1][p] - aF[j][p]); } ierr = DMDAVecRestoreArrayDOF(da, u, &au);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da, F, &aF);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da, unew, &aunew);CHKERRQ(ierr); t += dt; } // clean up ierr = VecDestroy(&u); CHKERRQ(ierr); ierr = VecDestroy(&unew); CHKERRQ(ierr); ierr = VecDestroy(&F); CHKERRQ(ierr); ierr = VecDestroy(&dq); CHKERRQ(ierr); ierr = VecDestroy(&qleft); CHKERRQ(ierr); ierr = VecDestroy(&tmp); CHKERRQ(ierr); ierr = VecDestroy(&Fcell); CHKERRQ(ierr); ierr = MatDestroy(&A); CHKERRQ(ierr); ierr = MatDestroy(&Aminus); CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr); ierr = DMDestroy(&da); CHKERRQ(ierr); ierr = PetscFinalize(); CHKERRQ(ierr); return 0; }