PetscErrorCode SetVariableBounds(DM da,Vec xl,Vec xu) { PetscErrorCode ierr; PetscScalar **l,**u; PetscInt xs,xm; PetscInt i; PetscFunctionBeginUser; ierr = DMDAVecGetArrayDOF(da,xl,&l);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,xu,&u);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); for (i=xs; i < xs+xm; i++) { l[i][0] = -SNES_VI_INF; l[i][1] = 0.0; l[i][2] = 0.0; u[i][0] = SNES_VI_INF; u[i][1] = 1.0; u[i][2] = 1.0; } ierr = DMDAVecRestoreArrayDOF(da,xl,&l);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da,xu,&u);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode SetVariableBounds(DM da,Vec xl,Vec xu) { PetscErrorCode ierr; PetscScalar ***l,***u; PetscInt xs,xm,ys,ym; PetscInt j,i; PetscFunctionBegin; ierr = DMDAVecGetArrayDOF(da,xl,&l);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,xu,&u);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);CHKERRQ(ierr); for(j=ys; j < ys+ym; j++) { for(i=xs; i < xs+xm;i++) { l[j][i][0] = -SNES_VI_INF; l[j][i][1] = -1.0; u[j][i][0] = SNES_VI_INF; u[j][i][1] = 1.0; } } ierr = DMDAVecRestoreArrayDOF(da,xl,&l);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da,xu,&u);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc, char *argv[]) { DM da, daX, daY; DMDALocalInfo info; MPI_Comm commX, commY; Vec basisX, basisY; PetscScalar **arrayX, **arrayY; const PetscInt *lx, *ly; PetscInt M = 3, N = 3; PetscInt p = 1; PetscInt numGP = 3; PetscInt dof = 2*(p+1)*numGP; PetscMPIInt rank, subsize, subrank; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&argv,0,help);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRQ(ierr); /* Create 2D DMDA */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_STAR, M, N, PETSC_DECIDE, PETSC_DECIDE, 1, 1, NULL, NULL, &da);CHKERRQ(ierr); /* Create 1D DMDAs along two directions */ ierr = DMDAGetOwnershipRanges(da, &lx, &ly, NULL);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(da, &info);CHKERRQ(ierr); ierr = DMDAGetProcessorSubsets(da, DMDA_X, &commX);CHKERRQ(ierr); ierr = DMDAGetProcessorSubsets(da, DMDA_Y, &commY);CHKERRQ(ierr); ierr = MPI_Comm_size(commX, &subsize);CHKERRQ(ierr); ierr = MPI_Comm_rank(commX, &subrank);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "[%d]X subrank: %d subsize: %d\n", rank, subrank, subsize); ierr = MPI_Comm_size(commY, &subsize);CHKERRQ(ierr); ierr = MPI_Comm_rank(commY, &subrank);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "[%d]Y subrank: %d subsize: %d\n", rank, subrank, subsize); ierr = DMDACreate1d(commX, DM_BOUNDARY_NONE, M, dof, 1, lx, &daX);CHKERRQ(ierr); ierr = DMDACreate1d(commY, DM_BOUNDARY_NONE, N, dof, 1, ly, &daY);CHKERRQ(ierr); /* Create 1D vectors for basis functions */ ierr = DMGetGlobalVector(daX, &basisX);CHKERRQ(ierr); ierr = DMGetGlobalVector(daY, &basisY);CHKERRQ(ierr); /* Extract basis functions */ ierr = DMDAVecGetArrayDOF(daX, basisX, &arrayX);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(daY, basisY, &arrayY);CHKERRQ(ierr); /*arrayX[i][ndof]; */ /*arrayY[j][ndof]; */ ierr = DMDAVecRestoreArrayDOF(daX, basisX, &arrayX);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(daY, basisY, &arrayY);CHKERRQ(ierr); /* Return basis vectors */ ierr = DMRestoreGlobalVector(daX, &basisX);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(daY, &basisY);CHKERRQ(ierr); /* Cleanup */ ierr = DMDestroy(&daX);CHKERRQ(ierr); ierr = DMDestroy(&daY);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PetscErrorCode SingleBodyPoints::calculateAvgForces(const Vec &f, type::RealVec1D &fAvg) const { PetscErrorCode ierr; PetscFunctionBeginUser; PetscReal **fArry; type::RealVec1D fAvgLocal(dim, 0.0); ierr = DMDAVecGetArrayDOF(da, f, &fArry); CHKERRQ(ierr); for (PetscInt i = bgPt; i < edPt; ++i) { for (PetscInt dof = 0; dof < dim; ++dof) { fAvgLocal[dof] -= fArry[i][dof]; // fArray is the force applied to fluid } } ierr = MPI_Barrier(comm); CHKERRQ(ierr); ierr = MPI_Allreduce(fAvgLocal.data(), fAvg.data(), dim, MPIU_REAL, MPI_SUM, comm); CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da, f, &fArry); CHKERRQ(ierr); PetscFunctionReturn(0); } // calculateAvgForces
/* Applies the second order centered difference diffusion operator on a one dimensional periodic domain */ static PetscErrorCode FormDiffusionFunction(TS ts,PetscReal t,Vec X,Vec F,void *ptr) { User user = (User)ptr; PetscErrorCode ierr; PetscScalar **f; const PetscScalar **x; DM dm; PetscInt i,xs,xm,j,dof; Vec Xlocal; PetscReal idx; PetscFunctionBeginUser; ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); ierr = DMDAGetInfo(dm,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dof,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); ierr = DMGetLocalVector(dm,&Xlocal);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm,X,INSERT_VALUES,Xlocal);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm,X,INSERT_VALUES,Xlocal);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOFRead(dm,Xlocal,&x);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(dm,F,&f);CHKERRQ(ierr); ierr = DMDAGetCorners(dm,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); idx = 1.0*user->diffus/user->dx; for (i=xs; i<xs+xm; i++) { for (j=0; j<dof; j++) { f[i][j] += idx*(x[i+1][j] - 2.0*x[i][j] + x[i-1][j]); } } ierr = DMDAVecRestoreArrayDOFRead(dm,Xlocal,&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(dm,F,&f);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm,&Xlocal);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode FormRHSFunction(TS ts,PetscReal t,Vec X,Vec F,void *ptr) { User user = (User)ptr; PetscErrorCode ierr; PetscScalar **f; const PetscScalar **x; DM dm; PetscInt i,xs,xm; PetscFunctionBeginUser; if (user->reactions) { ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOFRead(dm,X,&x);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(dm,F,&f);CHKERRQ(ierr); ierr = DMDAGetCorners(dm,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); for (i=xs; i<xs+xm; i++) { ierr = PetscMemcpy(user->tchemwork,x[i],(user->Nspec+1)*sizeof(x[xs][0]));CHKERRQ(ierr); user->tchemwork[0] *= user->Tini; /* Dimensionalize */ ierr = TC_getSrc(user->tchemwork,user->Nspec+1,f[i]);TCCHKERRQ(ierr); f[i][0] /= user->Tini; /* Non-dimensionalize */ } ierr = DMDAVecRestoreArrayDOFRead(dm,X,&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(dm,F,&f);CHKERRQ(ierr); } else { ierr = VecZeroEntries(F);CHKERRQ(ierr); } if (user->diffusion) { ierr = FormDiffusionFunction(ts,t,X,F,ptr);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode DMDAVecGenerateEntries(DM dm,Vec a) { PetscScalar ****LA_v; PetscInt i,j,k,si,sj,sk,ni,nj,nk,M,N; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = DMDAGetInfo(dm,NULL,&M,&N,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); ierr = DMDAGetCorners(dm,&si,&sj,&sk,&ni,&nj,&nk);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(dm,a,&LA_v);CHKERRQ(ierr); for (k=sk; k<sk+nk; k++) { for (j=sj; j<sj+nj; j++) { for (i=si; i<si+ni; i++) { PetscScalar test_value_s; test_value_s = dmda_i_val[i]*((PetscScalar)i) + dmda_j_val[j]*((PetscScalar)(i+j*M)) + dmda_k_val[k]*((PetscScalar)(i + j*M + k*M*N)); LA_v[k][j][i][0] = 3.0 * test_value_s; LA_v[k][j][i][1] = 3.0 * test_value_s + 1.0; LA_v[k][j][i][2] = 3.0 * test_value_s + 2.0; } } } ierr = DMDAVecRestoreArrayDOF(dm,a,&LA_v);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode FormInitialSolution(TS ts,Vec X,void *ctx) { PetscScalar **x,*xc; PetscErrorCode ierr; struct {const char *name; PetscReal massfrac;} initial[] = { {"CH4", 0.0948178320887}, {"O2", 0.189635664177}, {"N2", 0.706766236705}, {"AR", 0.00878026702874} }; PetscInt i,j,xs,xm; DM dm; PetscFunctionBeginUser; ierr = VecZeroEntries(X);CHKERRQ(ierr); ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); ierr = DMDAGetCorners(dm,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); ierr = DMDAGetCoordinateArray(dm,&xc);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(dm,X,&x);CHKERRQ(ierr); for (i=xs; i<xs+xm; i++) { x[i][0] = 1.0 + .05*PetscSinScalar(2.*PETSC_PI*xc[i]); /* Non-dimensionalized by user->Tini */ for (j=0; j<sizeof(initial)/sizeof(initial[0]); j++) { int ispec = TC_getSpos(initial[j].name, strlen(initial[j].name)); if (ispec < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Could not find species %s",initial[j].name); ierr = PetscPrintf(PETSC_COMM_SELF,"Species %d: %s %g\n",j,initial[j].name,initial[j].massfrac);CHKERRQ(ierr); x[i][1+ispec] = initial[j].massfrac; } } ierr = DMDAVecRestoreArrayDOF(dm,X,&x);CHKERRQ(ierr); ierr = DMDARestoreCoordinateArray(dm,&xc);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode FormInitialSolution(DM da,Vec U) { PetscErrorCode ierr; PetscInt i,j,xs,ys,xm,ym,Mx,My; PetscScalar ***u; PetscReal hx,hy,x,y,r; PetscFunctionBeginUser; ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE); hx = 1.0/(PetscReal)(Mx-1); hy = 1.0/(PetscReal)(My-1); /* Get pointers to vector data */ ierr = DMDAVecGetArrayDOF(da,U,&u);CHKERRQ(ierr); /* Get local grid boundaries */ ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (j=ys; j<ys+ym; j++) { y = j*hy; for (i=xs; i<xs+xm; i++) { x = i*hx; r = PetscSqrtReal((x-.5)*(x-.5) + (y-.5)*(y-.5)); if (r < .125) { u[j][i][0] = PetscExpReal(-30.0*r*r*r); u[j][i][1] = 0.0; } else { u[j][i][0] = 0.0; u[j][i][1] = 0.0; } } } /* Restore vectors */ ierr = DMDAVecRestoreArrayDOF(da,U,&u);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt M = -2, N = -3, P = 4,stencil_width = 1, dof = 1,m,n,p,xstart,ystart,zstart,i,j,k,c; DM da; Vec global,local; PetscScalar ****vglobal; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); PetscFunctionBeginUser; ierr = PetscOptionsGetInt(0,"-stencil_width",&stencil_width,0);CHKERRQ(ierr); ierr = PetscOptionsGetInt(0,"-dof",&dof,0);CHKERRQ(ierr); ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_MIRROR,DM_BOUNDARY_MIRROR,DM_BOUNDARY_MIRROR,DMDA_STENCIL_STAR,M,N,P,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,dof,stencil_width,NULL,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xstart,&ystart,&zstart,&m,&n,&p);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,global,&vglobal);CHKERRQ(ierr); for (k=zstart; k<zstart+p; k++) { for (j=ystart; j<ystart+n; j++) { for (i=xstart; i<xstart+m; i++) { for (c=0; c<dof; c++) { vglobal[k][j][i][c] = 1000*k + 100*j + 10*(i+1) + c; } } } } ierr = DMDAVecRestoreArrayDOF(da,global,&vglobal);CHKERRQ(ierr); ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = PetscSequentialPhaseBegin(PETSC_COMM_WORLD,1);CHKERRQ(ierr); ierr = VecView(local,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = PetscSequentialPhaseEnd(PETSC_COMM_WORLD,1);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = VecDestroy(&local);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt M = 6,stencil_width = 1, dof = 1,m,xstart,i,j; DM da; Vec global,local; PetscScalar **vglobal; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); PetscFunctionBeginUser; ierr = PetscOptionsGetInt(0,"-stencil_width",&stencil_width,0);CHKERRQ(ierr); ierr = PetscOptionsGetInt(0,"-dof",&dof,0);CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_MIRROR,M,dof,stencil_width,NULL,&da);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xstart,0,0,&m,0,0);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,global,&vglobal);CHKERRQ(ierr); for (i=xstart; i<xstart+m; i++) { for (j=0; j<dof; j++) { vglobal[i][j] = 100*(i+1) + j; } } ierr = DMDAVecRestoreArrayDOF(da,global,&vglobal);CHKERRQ(ierr); ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = PetscSequentialPhaseBegin(PETSC_COMM_WORLD,1);CHKERRQ(ierr); ierr = VecView(local,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = PetscSequentialPhaseEnd(PETSC_COMM_WORLD,1);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = VecDestroy(&local);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscInt M = 6,N = 5,P = 4, m = PETSC_DECIDE,n = PETSC_DECIDE,p = PETSC_DECIDE,i,j,k,is,js,ks,in,jen,kn; PetscErrorCode ierr; DM da; Vec local,global; PetscScalar ****l; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; /* Create distributed array and get vectors */ ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,M,N,P,m,n,p,2,1,NULL,NULL,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 = DMDAGetCorners(da,&is,&js,&ks,&in,&jen,&kn);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,local,&l);CHKERRQ(ierr); for (i=is; i<is+in; i++) { for (j=js; j<js+jen; j++) { for (k=ks; k<ks+kn; k++) { l[k][j][i][0] = 2*(i + j*M + k*M*N); l[k][j][i][1] = 2*(i + j*M + k*M*N) + 1; } } } ierr = DMDAVecRestoreArrayDOF(da,local,&l);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(da,local,ADD_VALUES,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(da,local,ADD_VALUES,global);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* Free memory */ 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) { PetscInt M = 6,N = 5,m = PETSC_DECIDE,n = PETSC_DECIDE,i,j,is,js,in,jen; PetscErrorCode ierr; DM da; Vec local,global; PetscScalar ***l; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); /* Create distributed array and get vectors */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE,DMDA_STENCIL_BOX,M,N,m,n,3,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&is,&js,0,&in,&jen,0);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,local,&l);CHKERRQ(ierr); for (i=is; i<is+in; i++) { for (j=js; j<js+jen; j++) { l[j][i][0] = 3*(i + j*M); l[j][i][1] = 3*(i + j*M) + 1; l[j][i][2] = 3*(i + j*M) + 2; } } ierr = DMDAVecRestoreArrayDOF(da,local,&l);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(da,local,ADD_VALUES,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(da,local,ADD_VALUES,global);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* Free memory */ ierr = VecDestroy(&local);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PetscErrorCode InitialConditions(DM da,Vec U) { PetscErrorCode ierr; PetscInt i,c,xs,xm,Mx,N; PetscScalar **u; PetscReal hx,x; PetscFunctionBegin; ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,&N,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); hx = 1.0/(PetscReal)(Mx-1); /* Get pointers to vector data */ ierr = DMDAVecGetArrayDOF(da,U,&u);CHKERRQ(ierr); /* Get local grid boundaries */ ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (i=xs; i<xs+xm; i++) { x = i*hx; for (c=0; c<N; c++) u[i][c] = 0.0; /*PetscCosScalar(PETSC_PI*x);*/ } /* Restore vectors */ ierr = DMDAVecRestoreArrayDOF(da,U,&u);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode IJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal a,Mat *J,Mat *Jpre,MatStructure *str,void *ctx) { PetscErrorCode ierr; PetscInt i,c,Mx,xs,xm,nc; DM da; MatStencil col[3],row; PetscScalar vals[3],hx,sx; AppCtx *user = (AppCtx*)ctx; PetscInt N = user->N; PetscScalar **u; PetscFunctionBegin; ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE); ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); hx = 1.0/(PetscReal)(Mx-1); sx = 1.0/(hx*hx); ierr = DMDAVecGetArrayDOF(da,U,&u);CHKERRQ(ierr); ierr = MatZeroEntries(*Jpre);CHKERRQ(ierr); for (i=xs; i<xs+xm; i++) { for (c=0; c<N; c++) { nc = 0; row.c = c; row.i = i; col[nc].c = c; col[nc].i = i-1; vals[nc++] = -sx; col[nc].c = c; col[nc].i = i; vals[nc++] = 2.0*sx + a; col[nc].c = c; col[nc].i = i+1; vals[nc++] = -sx; ierr = MatSetValuesStencil(*Jpre,1,&row,nc,col,vals,ADD_VALUES);CHKERRQ(ierr); } for (c=0; c<N/3; c++) { nc = 0; row.c = c; row.i = i; col[nc].c = c; col[nc].i = i; vals[nc++] = 1000*u[i][c] + 500*u[i][c+1]; col[nc].c = c+1; col[nc].i = i; vals[nc++] = 500*u[i][c]; ierr = MatSetValuesStencil(*Jpre,1,&row,nc,col,vals,ADD_VALUES);CHKERRQ(ierr); nc = 0; row.c = c+1; row.i = i; col[nc].c = c; col[nc].i = i; vals[nc++] = -1000*u[i][c] + 500*u[i][c+1]; col[nc].c = c+1; col[nc].i = i; vals[nc++] = 500*u[i][c]; ierr = MatSetValuesStencil(*Jpre,1,&row,nc,col,vals,ADD_VALUES);CHKERRQ(ierr); nc = 0; row.c = c+2; row.i = i; col[nc].c = c; col[nc].i = i; vals[nc++] = -500*u[i][c+1]; col[nc].c = c+1; col[nc].i = i; vals[nc++] = -500*u[i][c]; ierr = MatSetValuesStencil(*Jpre,1,&row,nc,col,vals,ADD_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(*Jpre,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*Jpre,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (*J != *Jpre) { ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } ierr = DMDAVecRestoreArrayDOF(da,U,&u);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* IFunction - Evaluates nonlinear function, F(U). Input Parameters: . ts - the TS context . U - input vector . ptr - optional user-defined context, as set by SNESSetFunction() Output Parameter: . F - function vector */ PetscErrorCode IFunction(TS ts,PetscReal ftime,Vec U,Vec Udot,Vec F,void *ptr) { DM da; PetscErrorCode ierr; PetscInt i,c,Mx,xs,xm,N; PetscReal hx,sx,x; PetscScalar uxx; PetscScalar **u,**f,**udot; Vec localU; PetscFunctionBegin; ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMGetLocalVector(da,&localU);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,&N,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); hx = 1.0/(PetscReal)(Mx-1); sx = 1.0/(hx*hx); /* Scatter ghost points to local vector,using the 2-step process DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ ierr = DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); /* Get pointers to vector data */ ierr = DMDAVecGetArrayDOF(da,localU,&u);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,Udot,&udot);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,F,&f);CHKERRQ(ierr); /* Get local grid boundaries */ ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (i=xs; i<xs+xm; i++) { x = i*hx; /* diffusion term */ for (c=0; c<N; c++) { uxx = (-2.0*u[i][c] + u[i-1][c] + u[i+1][c])*sx; f[i][c] = udot[i][c] - uxx; } /* reaction terms */ for (c=0; c<N/3; c++) { f[i][c] += 500*u[i][c]*u[i][c] + 500*u[i][c]*u[i][c+1]; f[i][c+1] += -500*u[i][c]*u[i][c] + 500*u[i][c]*u[i][c+1]; f[i][c+2] -= 500*u[i][c]*u[i][c+1]; } /* forcing term */ f[i][0] -= 5*PetscExpScalar((1.0 - x)*(1.0 - x)); } /* Restore vectors */ ierr = DMDAVecRestoreArrayDOF(da,localU,&u);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da,Udot,&udot);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da,F,&f);CHKERRQ(ierr); ierr = DMRestoreLocalVector(da,&localU);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscInt M = 10,N = 8,dof=1,s=1,bx=0,by=0,i,n,j,k,m,wrap,xs,ys; PetscErrorCode ierr; DM da,dac; PetscViewer viewer; Vec local,global,coors; PetscScalar ***xy,***aglobal; PetscDraw draw; char fname[16]; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; /* Create viewers */ ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"",PETSC_DECIDE,PETSC_DECIDE,600,200,&viewer);CHKERRQ(ierr); ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr); /* Read options */ 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,"-s",&s,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-periodic_x",&wrap,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-periodic_y",&wrap,NULL);CHKERRQ(ierr); /* Create distributed array and get vectors */ ierr = DMDACreate2d(PETSC_COMM_WORLD,(DMBoundaryType)bx,(DMBoundaryType)by,DMDA_STENCIL_BOX,M,N,PETSC_DECIDE,PETSC_DECIDE,dof,s,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,0.0);CHKERRQ(ierr); for (i=0; i<dof; i++) { sprintf(fname,"Field %d",(int)i); ierr = DMDASetFieldName(da,i,fname);CHKERRQ(ierr); } ierr = DMView(da,viewer);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&coors);CHKERRQ(ierr); ierr = DMGetCoordinateDM(da,&dac);CHKERRQ(ierr); /* Set values into global vectors */ ierr = DMDAVecGetArrayDOFRead(dac,coors,&xy);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,global,&aglobal);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,&ys,0,&m,&n,0);CHKERRQ(ierr); for (k=0; k<dof; k++) { for (j=ys; j<ys+n; j++) { for (i=xs; i<xs+m; i++) { aglobal[j][i][k] = PetscSinScalar(2.0*PETSC_PI*(k+1)*xy[j][i][0]); } } } ierr = DMDAVecRestoreArrayDOF(da,global,&aglobal);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOFRead(dac,coors,&xy);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = VecSet(global,0.0);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(da,local,INSERT_VALUES,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(da,local,INSERT_VALUES,global);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(global,viewer);CHKERRQ(ierr); /* Free memory */ ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = VecDestroy(&local);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
/* FormFunction - Evaluates nonlinear function, F(x). Input Parameters: . ts - the TS context . X - input vector . ptr - optional user-defined context, as set by SNESSetFunction() Output Parameter: . F - function vector */ PetscErrorCode FormFunction(TS ts,PetscReal ftime,Vec X,Vec F,void *ptr) { DM da = (DM)ptr; PetscErrorCode ierr; PetscInt i,j,Mx,My,xs,ys,xm,ym; PetscReal hx,hy,/*hxdhy,hydhx,*/ sx,sy; PetscScalar u,uxx,uyy,v,***x,***f; Vec localX; PetscFunctionBeginUser; ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE); hx = 1.0/(PetscReal)(Mx-1); sx = 1.0/(hx*hx); hy = 1.0/(PetscReal)(My-1); sy = 1.0/(hy*hy); /*hxdhy = hx/hy;*/ /*hydhx = hy/hx;*/ /* Scatter ghost points to local vector,using the 2-step process DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); /* Get pointers to vector data */ ierr = DMDAVecGetArrayDOF(da,localX,&x);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,F,&f);CHKERRQ(ierr); /* Get local grid boundaries */ ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { if (i == 0 || j == 0 || i == Mx-1 || j == My-1) { f[j][i][0] = x[j][i][0]; f[j][i][1] = x[j][i][1]; continue; } u = x[j][i][0]; v = x[j][i][1]; uxx = (-2.0*u + x[j][i-1][0] + x[j][i+1][0])*sx; uyy = (-2.0*u + x[j-1][i][0] + x[j+1][i][0])*sy; f[j][i][0] = v; f[j][i][1] = uxx + uyy; } } /* Restore vectors */ ierr = DMDAVecRestoreArrayDOF(da,localX,&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da,F,&f);CHKERRQ(ierr); ierr = DMRestoreLocalVector(da,&localX);CHKERRQ(ierr); ierr = PetscLogFlops(11.0*ym*xm);CHKERRQ(ierr); PetscFunctionReturn(0); }
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; }
PetscErrorCode CheckRedundancy(SNES snes, IS act, IS *outact, DM da) { PetscErrorCode ierr; PetscScalar **uin,**uout; Vec UIN, UOUT; PetscInt xs,xm,*outindex; const PetscInt *index; PetscInt k,i,l,n,M,cnt=0; PetscFunctionBeginUser; ierr = DMDAGetInfo(da,0,&M,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); ierr = DMGetGlobalVector(da,&UIN);CHKERRQ(ierr); ierr = VecSet(UIN,0.0);CHKERRQ(ierr); ierr = DMGetLocalVector(da,&UOUT);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,UIN,&uin);CHKERRQ(ierr); ierr = ISGetIndices(act,&index);CHKERRQ(ierr); ierr = ISGetLocalSize(act,&n);CHKERRQ(ierr); for (k=0; k<n; k++) { l = index[k]%5; i = index[k]/5; uin[i][l]=1.0; } printf("Number of active constraints before applying redundancy %d\n",n); ierr = ISRestoreIndices(act,&index);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da,UIN,&uin);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,UIN,INSERT_VALUES,UOUT);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,UIN,INSERT_VALUES,UOUT);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,UOUT,&uout);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); for (i=xs; i < xs+xm;i++) { if (uout[i-1][1] && uout[i][1] && uout[i+1][1]) uout[i][0] = 1.0; if (uout[i-1][3] && uout[i][3] && uout[i+1][3]) uout[i][2] = 1.0; } for (i=xs; i < xs+xm; i++) { for (l=0; l < 5; l++) { if (uout[i][l]) cnt++; } } printf("Number of active constraints after applying redundancy %d\n",cnt); ierr = PetscMalloc(cnt*sizeof(PetscInt),&outindex);CHKERRQ(ierr); cnt = 0; for (i=xs; i < xs+xm;i++) { for (l=0;l<5;l++) { if (uout[i][l]) outindex[cnt++] = 5*(i)+l; } } ierr = ISCreateGeneral(PETSC_COMM_WORLD,cnt,outindex,PETSC_OWN_POINTER,outact);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da,UOUT,&uout);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&UIN);CHKERRQ(ierr); ierr = DMRestoreLocalVector(da,&UOUT);CHKERRQ(ierr); PetscFunctionReturn(0); }
EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "DMConvert_DA_Mesh" PetscErrorCode DMConvert_DA_Mesh(DM dm, const DMType newtype, DM *dmNew) { PetscSection section; DM cda; DMDALocalInfo info; Vec coordinates; PetscInt *cone, *coneO; PetscInt dim, M, N, P, numCells, numGlobalCells, numCorners, numVertices, c = 0, v = 0; PetscInt ye, ze; PetscInt debug = 0; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscOptionsGetInt(PETSC_NULL, "-dm_mesh_debug", &debug, PETSC_NULL);CHKERRQ(ierr); ierr = DMDAGetInfo(dm, &dim, &M, &N, &P, 0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dm, &info);CHKERRQ(ierr); if (info.sw > 1) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Currently, only DMDAs with unti stencil width can be converted to DMMeshes."); /* In order to get a partition of cells, rather than vertices, we give each process the cells between vertices it owns and also higher numbered ghost vertices (vertices to the right and up) */ numCorners = 1 << dim; numCells = ((info.gxm+info.gxs - info.xs) - 1); if (dim > 1) {numCells *= ((info.gym+info.gys - info.ys) - 1);} if (dim > 2) {numCells *= ((info.gzm+info.gzs - info.zs) - 1);} numVertices = (info.gxm+info.gxs - info.xs); if (dim > 1) {numVertices *= (info.gym+info.gys - info.ys);} if (dim > 2) {numVertices *= (info.gzm+info.gzs - info.zs);} numGlobalCells = M-1; if (dim > 1) {numGlobalCells *= N-1;} if (dim > 2) {numGlobalCells *= P-1;} ALE::Obj<PETSC_MESH_TYPE> mesh = new PETSC_MESH_TYPE(((PetscObject) dm)->comm, info.dim, debug); ALE::Obj<PETSC_MESH_TYPE::sieve_type> sieve = new PETSC_MESH_TYPE::sieve_type(((PetscObject) dm)->comm, 0, numCells+numVertices, debug); PETSC_MESH_TYPE::renumbering_type renumbering; mesh->setSieve(sieve); /* Number each cell for the vertex in the lower left corner */ if (dim < 3) {ze = 1; P = 1;} else {ze = info.gzs+info.gzm-1;} if (dim < 2) {ye = 1; N = 1;} else {ye = info.gys+info.gym-1;} for(PetscInt k = info.zs; k < ze; ++k) { for(PetscInt j = info.ys; j < ye; ++j) { for(PetscInt i = info.xs; i < info.gxs+info.gxm-1; ++i, ++c) { PetscInt globalC = (k*(N-1) + j)*(M-1) + i; renumbering[globalC] = c; sieve->setConeSize(c, numCorners); } } } if (c != numCells) {SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "Error in generated cell numbering, %d should be %d", c, numCells);} /* Get vertex renumbering */ for(PetscInt k = info.zs; k < info.gzs+info.gzm; ++k) { for(PetscInt j = info.ys; j < info.gys+info.gym; ++j) { for(PetscInt i = info.xs; i < info.gxs+info.gxm; ++i, ++v) { PetscInt globalV = (k*N + j)*M + i + numGlobalCells; renumbering[globalV] = v+numCells; } } } if (v != numVertices) {SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_PLIB, "Error in generated vertex numbering, %d should be %d", v, numVertices);} /* Calculate support sizes */ for(PetscInt k = info.zs; k < ze; ++k, ++c) { for(PetscInt j = info.ys; j < ye; ++j) { for(PetscInt i = info.xs; i < info.gxs+info.gxm-1; ++i) { for(PetscInt kp = k; kp <= k+(dim>2); ++kp) { for(PetscInt jp = j; jp <= j+(dim>1); ++jp) { for(PetscInt ip = i; ip <= i+1; ++ip) { PetscInt globalV = (kp*N + jp)*M + ip + numGlobalCells; sieve->addSupportSize(renumbering[globalV], 1); } } } } } } sieve->allocate(); ierr = PetscMalloc2(numCorners,PetscInt,&cone,numCorners,PetscInt,&coneO);CHKERRQ(ierr); for(PetscInt v = 0; v < numCorners; ++v) { coneO[v] = 1; } for(PetscInt k = info.zs; k < ze; ++k) { for(PetscInt j = info.ys; j < ye; ++j) { for(PetscInt i = info.xs; i < info.gxs+info.gxm-1; ++i) { PetscInt globalC = (k*(N-1) + j)*(M-1) + i; PetscInt v = 0; cone[v++] = renumbering[(k*N + j)*M + i+0 + numGlobalCells]; cone[v++] = renumbering[(k*N + j)*M + i+1 + numGlobalCells]; if (dim > 1) { cone[v++] = renumbering[(k*N + j+1)*M + i+0 + numGlobalCells]; cone[v++] = renumbering[(k*N + j+1)*M + i+1 + numGlobalCells]; } if (dim > 2) { cone[v++] = renumbering[((k+1)*N + j+0)*M + i+0 + numGlobalCells]; cone[v++] = renumbering[((k+1)*N + j+0)*M + i+1 + numGlobalCells]; cone[v++] = renumbering[((k+1)*N + j+1)*M + i+0 + numGlobalCells]; cone[v++] = renumbering[((k+1)*N + j+1)*M + i+1 + numGlobalCells]; } sieve->setCone(cone, renumbering[globalC]); sieve->setConeOrientation(coneO, renumbering[globalC]); } } } ierr = PetscFree2(cone,coneO);CHKERRQ(ierr); sieve->symmetrize(); mesh->stratify(); /* Create boundary marker */ { const Obj<PETSC_MESH_TYPE::label_type>& boundary = mesh->createLabel("marker"); for(PetscInt k = info.zs; k < info.gzs+info.gzm; ++k) { for(PetscInt j = info.ys; j < info.gys+info.gym; ++j) { if (info.xs == 0) { PetscInt globalV = (k*N + j)*M + info.xs + numGlobalCells; mesh->setValue(boundary, renumbering[globalV], 1); } if (info.gxs+info.gxm-1 == M-1) { PetscInt globalV = (k*N + j)*M + info.gxs+info.gxm-1 + numGlobalCells; mesh->setValue(boundary, renumbering[globalV], 1); } } } if (dim > 1) { for(PetscInt k = info.zs; k < info.gzs+info.gzm; ++k) { for(PetscInt i = info.xs; i < info.gxs+info.gxm; ++i) { if (info.ys == 0) { PetscInt globalV = (k*N + info.ys)*M + i + numGlobalCells; mesh->setValue(boundary, renumbering[globalV], 1); } if (info.gys+info.gym-1 == N-1) { PetscInt globalV = (k*N + info.gys+info.gym-1)*M + i + numGlobalCells; mesh->setValue(boundary, renumbering[globalV], 1); } } } } if (dim > 2) { for(PetscInt j = info.ys; j < info.gys+info.gym; ++j) { for(PetscInt i = info.xs; i < info.gxs+info.gxm; ++i) { if (info.zs == 0) { PetscInt globalV = (info.zs*N + j)*M + i + numGlobalCells; mesh->setValue(boundary, renumbering[globalV], 1); } if (info.gzs+info.gzm-1 == P-1) { PetscInt globalV = ((info.gzs+info.gzm-1)*N + j)*M + i + numGlobalCells; mesh->setValue(boundary, renumbering[globalV], 1); } } } } } /* Create new DM */ ierr = DMMeshCreate(((PetscObject) dm)->comm, dmNew);CHKERRQ(ierr); ierr = DMMeshSetMesh(*dmNew, mesh);CHKERRQ(ierr); /* Set coordinates */ ierr = PetscSectionCreate(((PetscObject) dm)->comm, §ion);CHKERRQ(ierr); ierr = PetscSectionSetChart(section, numCells, numCells+numVertices);CHKERRQ(ierr); for(PetscInt v = numCells; v < numCells+numVertices; ++v) { ierr = PetscSectionSetDof(section, v, dim);CHKERRQ(ierr); } ierr = PetscSectionSetUp(section);CHKERRQ(ierr); ierr = DMMeshSetCoordinateSection(*dmNew, section);CHKERRQ(ierr); ierr = DMDAGetCoordinateDA(dm, &cda);CHKERRQ(ierr); ierr = DMDAGetGhostedCoordinates(dm, &coordinates);CHKERRQ(ierr); { Obj<PETSC_MESH_TYPE::real_section_type> coordSection = mesh->getRealSection("coordinates"); switch(dim) { case 1: { PetscScalar **coords; ierr = DMDAVecGetArrayDOF(cda, coordinates, &coords);CHKERRQ(ierr); for(PetscInt i = info.xs; i < info.gxs+info.gxm; ++i) { PetscInt globalV = i + numGlobalCells; coordSection->updatePoint(renumbering[globalV], coords[i]); } ierr = DMDAVecRestoreArrayDOF(cda, coordinates, &coords);CHKERRQ(ierr); break; } case 2: { PetscScalar ***coords; ierr = DMDAVecGetArrayDOF(cda, coordinates, &coords);CHKERRQ(ierr); for(PetscInt j = info.ys; j < info.gys+info.gym; ++j) { for(PetscInt i = info.xs; i < info.gxs+info.gxm; ++i) { PetscInt globalV = j*M + i + numGlobalCells; coordSection->updatePoint(renumbering[globalV], coords[j][i]); } } ierr = DMDAVecRestoreArrayDOF(cda, coordinates, &coords);CHKERRQ(ierr); break; } case 3: { PetscScalar ****coords; ierr = DMDAVecGetArrayDOF(cda, coordinates, &coords);CHKERRQ(ierr); for(PetscInt k = info.zs; k < info.gzs+info.gzm; ++k, ++v) { for(PetscInt j = info.ys; j < info.gys+info.gym; ++j) { for(PetscInt i = info.xs; i < info.gxs+info.gxm; ++i) { PetscInt globalV = (k*N + j)*M + i + numGlobalCells; coordSection->updatePoint(renumbering[globalV], coords[k][j][i]); } } } ierr = DMDAVecRestoreArrayDOF(cda, coordinates, &coords);CHKERRQ(ierr); break; } default: SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid DMDA dimension %d", dim); } } /* Get overlap for interdomain communication */ { typedef PETSC_MESH_TYPE::point_type point_type; PETSc::Log::Event("CreateOverlap").begin(); ALE::Obj<PETSC_MESH_TYPE::send_overlap_type> sendParallelMeshOverlap = mesh->getSendOverlap(); ALE::Obj<PETSC_MESH_TYPE::recv_overlap_type> recvParallelMeshOverlap = mesh->getRecvOverlap(); // Can I figure this out in a nicer way? ALE::SetFromMap<std::map<point_type,point_type> > globalPoints(renumbering); ALE::OverlapBuilder<>::constructOverlap(globalPoints, renumbering, sendParallelMeshOverlap, recvParallelMeshOverlap); if (debug) { sendParallelMeshOverlap->view("Send Overlap"); recvParallelMeshOverlap->view("Recieve Overlap"); } mesh->setCalculatedOverlap(true); PETSc::Log::Event("CreateOverlap").end(); } PetscFunctionReturn(0); }