PetscErrorCode DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v) { PetscErrorCode ierr; PetscInt m,n,M,N,nDM,i; struct DMCompositeLink *nextc; struct DMCompositeLink *nextf; Vec gcoarse,gfine,*vecs; DM_Composite *comcoarse = (DM_Composite*)coarse->data; DM_Composite *comfine = (DM_Composite*)fine->data; Mat *mats; PetscFunctionBegin; PetscValidHeaderSpecific(coarse,DM_CLASSID,1); PetscValidHeaderSpecific(fine,DM_CLASSID,2); ierr = DMSetUp(coarse);CHKERRQ(ierr); ierr = DMSetUp(fine);CHKERRQ(ierr); /* use global vectors only for determining matrix layout */ ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr); ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr); ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr); ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr); ierr = VecGetSize(gfine,&M);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr); nDM = comfine->nDM; if (nDM != comcoarse->nDM) SETERRQ2(((PetscObject)fine)->comm,PETSC_ERR_ARG_INCOMP,"Fine DMComposite has %D entries, but coarse has %D",nDM,comcoarse->nDM); ierr = PetscMalloc(nDM*nDM*sizeof(Mat),&mats);CHKERRQ(ierr); ierr = PetscMemzero(mats,nDM*nDM*sizeof(Mat));CHKERRQ(ierr); if (v) { ierr = PetscMalloc(nDM*sizeof(Vec),&vecs);CHKERRQ(ierr); ierr = PetscMemzero(vecs,nDM*sizeof(Vec));CHKERRQ(ierr); } /* loop over packed objects, handling one at at time */ for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) { if (!v) { ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],PETSC_NULL);CHKERRQ(ierr); } else { ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr); } } ierr = MatCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,nDM,PETSC_NULL,mats,A);CHKERRQ(ierr); if (v) { ierr = VecCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,vecs,v);CHKERRQ(ierr); } for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);} ierr = PetscFree(mats);CHKERRQ(ierr); if (v) { for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);} ierr = PetscFree(vecs);CHKERRQ(ierr); } PetscFunctionReturn(0); }
int main(int argc, char **argv) { SNES snes; /* nonlinear solver */ DM da; /* grid */ Vec u; /* solution vector */ AppCtx user; /* user-defined work context */ PetscReal t; /* time */ PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, PETSC_NULL, help);CHKERRQ(ierr); /* Create solver */ ierr = SNESCreate(PETSC_COMM_WORLD, &snes);CHKERRQ(ierr); /* Create mesh */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,-4,3,1,PETSC_NULL,&da);CHKERRQ(ierr); ierr = DMSetApplicationContext(da, &user);CHKERRQ(ierr); ierr = SNESSetDM(snes, da);CHKERRQ(ierr); /* Create coefficient */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,-4,1,1,PETSC_NULL,&user.cda);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(user.cda, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr); ierr = DMGetGlobalVector(user.cda, &user.Kappa);CHKERRQ(ierr); ierr = FormPermeability(user.cda, user.Kappa, &user);CHKERRQ(ierr); /* Setup Problem */ ierr = DMDASetLocalFunction(da, (DMDALocalFunction1) FormFunctionLocal);CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &u);CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &user.uold);CHKERRQ(ierr); user.sl = 1.0; user.vl = 0.1; user.pl = 1.0; user.phi = 1.0; user.kappaWet = 1.0; user.kappaNoWet = 0.3; /* Time Loop */ user.dt = 0.1; for(PetscInt n = 0; n < 100; ++n, t += user.dt) { ierr = PetscPrintf(PETSC_COMM_WORLD, "Starting time %g\n", t);CHKERRQ(ierr); ierr = VecView(u, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr); /* Solve */ ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes, PETSC_NULL, u);CHKERRQ(ierr); /* Update */ ierr = VecCopy(u, user.uold);CHKERRQ(ierr); ierr = VecView(u, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr); } /* Cleanup */ ierr = DMRestoreGlobalVector(da, &u);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da, &user.uold);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(user.cda, &user.Kappa);CHKERRQ(ierr); ierr = DMDestroy(&user.cda);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscFinalize(); return 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; }
/*@C KSPGetVecs - Gets a number of work vectors. Input Parameters: + ksp - iterative context . rightn - number of right work vectors - leftn - number of left work vectors to allocate Output Parameter: + right - the array of vectors created - left - the array of left vectors Note: The right vector has as many elements as the matrix has columns. The left vector has as many elements as the matrix has rows. Level: advanced .seealso: MatGetVecs() @*/ PetscErrorCode KSPGetVecs(KSP ksp,PetscInt rightn, Vec **right,PetscInt leftn,Vec **left) { PetscErrorCode ierr; Vec vecr,vecl; PetscFunctionBegin; if (rightn) { if (!right) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_INCOMP,"You asked for right vectors but did not pass a pointer to hold them"); if (ksp->vec_sol) vecr = ksp->vec_sol; else { if (ksp->dm) { ierr = DMGetGlobalVector(ksp->dm,&vecr);CHKERRQ(ierr); } else { Mat mat; if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);} ierr = PCGetOperators(ksp->pc,&mat,NULL,NULL);CHKERRQ(ierr); ierr = MatGetVecs(mat,&vecr,NULL);CHKERRQ(ierr); } } ierr = VecDuplicateVecs(vecr,rightn,right);CHKERRQ(ierr); if (!ksp->vec_sol) { if (ksp->dm) { ierr = DMRestoreGlobalVector(ksp->dm,&vecr);CHKERRQ(ierr); } else { ierr = VecDestroy(&vecr);CHKERRQ(ierr); } } } if (leftn) { if (!left) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_INCOMP,"You asked for left vectors but did not pass a pointer to hold them"); if (ksp->vec_rhs) vecl = ksp->vec_rhs; else { if (ksp->dm) { ierr = DMGetGlobalVector(ksp->dm,&vecl);CHKERRQ(ierr); } else { Mat mat; if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);} ierr = PCGetOperators(ksp->pc,&mat,NULL,NULL);CHKERRQ(ierr); ierr = MatGetVecs(mat,NULL,&vecl);CHKERRQ(ierr); } } ierr = VecDuplicateVecs(vecl,leftn,left);CHKERRQ(ierr); if (!ksp->vec_rhs) { if (ksp->dm) { ierr = DMRestoreGlobalVector(ksp->dm,&vecl);CHKERRQ(ierr); } else { ierr = VecDestroy(&vecl);CHKERRQ(ierr); } } } PetscFunctionReturn(0); }
/*@C DMCompositeRestoreAccess - Returns the vectors obtained with DMCompositeGetAccess() representation. Collective on DMComposite Input Parameters: + dm - the packer object . gvec - the global vector - Vec* ... - the individual parallel vectors, PETSC_NULL for those that are not needed Level: advanced .seealso DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGather(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeScatter(), DMCompositeRestoreAccess(), DMCompositeGetAccess() @*/ PetscErrorCode DMCompositeRestoreAccess(DM dm,Vec gvec,...) { va_list Argp; PetscErrorCode ierr; struct DMCompositeLink *next; DM_Composite *com = (DM_Composite*)dm->data; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); next = com->next; if (!com->setup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } /* loop over packed objects, handling one at at time */ va_start(Argp,gvec); while (next) { Vec *vec; vec = va_arg(Argp, Vec*); if (vec) { ierr = VecResetArray(*vec);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(next->dm,vec);CHKERRQ(ierr); } next = next->next; } va_end(Argp); PetscFunctionReturn(0); }
/* Caculate the source term of the equations, which includes all terms except convetion term, diffusion term, and timedependent term. */ PetscErrorCode CaculateLocalSourceTerm(DM dm, Vec locX, Vec F, User user) { PetscErrorCode ierr; DM dmGrad = user->dmGrad; const PetscScalar *x; PetscScalar *f; PetscInt cStart, cell; const PetscScalar *cellgeom; const CellGeom *cg; Vec locGrad, Grad; const PetscScalar *grad; DM dmCell; PetscFunctionBeginUser; ierr = VecGetDM(user->cellgeom,&dmCell);CHKERRQ(ierr); ierr = VecGetArrayRead(locX,&x);CHKERRQ(ierr); ierr = VecGetArray(F,&f);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr); ierr = VecGetArrayRead(user->cellgeom,&cellgeom);CHKERRQ(ierr); ierr = DMGetGlobalVector(dmGrad,&Grad);CHKERRQ(ierr); ierr = DMGetLocalVector(dmGrad,&locGrad);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dmGrad,Grad,INSERT_VALUES,locGrad);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dmGrad,Grad,INSERT_VALUES,locGrad);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dmGrad,&Grad);CHKERRQ(ierr); ierr = VecGetArrayRead(locGrad,&grad);CHKERRQ(ierr); for (cell = cStart; cell < user->cEndInterior; cell++) { PetscScalar *fref; const PetscScalar *xref; PetscScalar *cgrad; ierr = DMPlexPointLocalRead(dmCell,cell,cellgeom,&cg);CHKERRQ(ierr); ierr = DMPlexPointLocalRead(dm,cell,x,&xref);CHKERRQ(ierr); /*For the unkown variables*/ ierr = DMPlexPointGlobalRef(dm,cell,f,&fref);CHKERRQ(ierr); ierr = DMPlexPointLocalRead(dmGrad,cell,grad,&cgrad);CHKERRQ(ierr); // if (!fref){ PetscPrintf(PETSC_COMM_WORLD,"%d, %d\n", cell, user->cEndInterior);} if (fref){ fref[0] += SourceRho(user, cgrad, xref, cg->centroid);/*the continuity equation*/ fref[1] += SourceU(user, cgrad, xref, cg->centroid); /*Momentum U*/ fref[2] += SourceV(user, cgrad, xref, cg->centroid); /*Momentum V*/ fref[3] += SourceW(user, cgrad, xref, cg->centroid); /*Momentum W*/ fref[4] += SourceE(user, cgrad, xref, cg->centroid);/*Energy*/ } } ierr = VecRestoreArrayRead(locX,&x);CHKERRQ(ierr); ierr = VecRestoreArray(F,&f);CHKERRQ(ierr); ierr = VecRestoreArrayRead(user->cellgeom,&cellgeom);CHKERRQ(ierr); ierr = VecRestoreArrayRead(locGrad,&grad);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dmGrad,&locGrad);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DMGlobalToLocalBegin_Composite(DM dm,Vec gvec,InsertMode mode,Vec lvec) { PetscErrorCode ierr; struct DMCompositeLink *next; PetscInt cnt = 3; PetscMPIInt rank; PetscScalar *garray,*larray; DM_Composite *com = (DM_Composite*)dm->data; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); next = com->next; if (!com->setup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); ierr = VecGetArray(gvec,&garray);CHKERRQ(ierr); ierr = VecGetArray(lvec,&larray);CHKERRQ(ierr); /* loop over packed objects, handling one at at time */ while (next) { Vec local,global; PetscInt N; ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); ierr = VecGetLocalSize(global,&N);CHKERRQ(ierr); ierr = VecPlaceArray(global,garray);CHKERRQ(ierr); ierr = DMGetLocalVector(next->dm,&local);CHKERRQ(ierr); ierr = VecPlaceArray(local,larray);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(next->dm,global,mode,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(next->dm,global,mode,local);CHKERRQ(ierr); ierr = VecResetArray(global);CHKERRQ(ierr); ierr = VecResetArray(local);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(next->dm,&local);CHKERRQ(ierr); cnt++; larray += next->nlocal; next = next->next; } ierr = VecRestoreArray(gvec,PETSC_NULL);CHKERRQ(ierr); ierr = VecRestoreArray(lvec,PETSC_NULL);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Compute the gradient of the variables at the center of the cell by the least-square reconstruction method based on the function BuildLeastSquares. */ PetscErrorCode ConstructCellCentriodGradient(DM dm,DM dmFace,DM dmCell,PetscReal time,Vec locX,Vec F,User user) { DM dmGrad = user->dmGrad; Model mod = user->model; Physics phys = mod->physics; const PetscInt dof = phys->dof; PetscErrorCode ierr; const PetscScalar *facegeom, *cellgeom, *x; PetscInt fStart, fEnd, face, cStart; Vec Grad; PetscFunctionBeginUser; ierr = DMGetGlobalVector(dmGrad,&Grad);CHKERRQ(ierr); ierr = VecZeroEntries(Grad);CHKERRQ(ierr); ierr = VecGetArrayRead(user->facegeom,&facegeom);CHKERRQ(ierr); ierr = VecGetArrayRead(user->cellgeom,&cellgeom);CHKERRQ(ierr); ierr = VecGetArrayRead(locX,&x);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr); { PetscScalar *grad; ierr = VecGetArray(Grad,&grad);CHKERRQ(ierr); /* Reconstruct gradients */ for (face=fStart; face<fEnd; face++) { const PetscInt *cells; const PetscScalar *cx[2]; const FaceGeom *fg; PetscScalar *cgrad[2]; PetscInt i,j; PetscBool ghost; ierr = IsExteriorGhostFace(dm,face,&ghost);CHKERRQ(ierr); if (ghost) continue; ierr = DMPlexGetSupport(dm,face,&cells);CHKERRQ(ierr); ierr = DMPlexPointLocalRead(dmFace,face,facegeom,&fg);CHKERRQ(ierr); for (i=0; i<2; i++) { ierr = DMPlexPointLocalRead(dm,cells[i],x,&cx[i]);CHKERRQ(ierr); ierr = DMPlexPointGlobalRef(dmGrad,cells[i],grad,&cgrad[i]);CHKERRQ(ierr); } for (i=0; i<dof; i++) { PetscScalar delta = cx[1][i] - cx[0][i]; for (j=0; j<DIM; j++) { if (cgrad[0]) cgrad[0][i*DIM+j] += fg->grad[0][j] * delta; if (cgrad[1]) cgrad[1][i*DIM+j] -= fg->grad[1][j] * delta; } } } ierr = VecRestoreArray(Grad,&grad);CHKERRQ(ierr); } ierr = DMRestoreGlobalVector(dmGrad,&Grad);CHKERRQ(ierr); ierr = VecRestoreArrayRead(user->facegeom,&facegeom);CHKERRQ(ierr); ierr = VecRestoreArrayRead(user->cellgeom,&cellgeom);CHKERRQ(ierr); ierr = VecRestoreArrayRead(locX,&x);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C DMCompositeGetISLocalToGlobalMappings - gets an ISLocalToGlobalMapping for each DM in the DMComposite, maps to the composite global space Collective on DM Input Parameter: . dm - the packer object Output Parameters: . ltogs - the individual mappings for each packed vector. Note that this includes all the ghost points that individual ghosted DMDA's may have. Level: advanced Notes: Each entry of ltogs should be destroyed with ISLocalToGlobalMappingDestroy(), the ltogs array should be freed with PetscFree(). .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeGather(), DMCompositeCreate(), DMCompositeGetAccess(), DMCompositeScatter(), DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(),DMCompositeGetEntries() @*/ PetscErrorCode DMCompositeGetISLocalToGlobalMappings(DM dm,ISLocalToGlobalMapping **ltogs) { PetscErrorCode ierr; PetscInt i,*idx,n,cnt; struct DMCompositeLink *next; PetscMPIInt rank; DM_Composite *com = (DM_Composite*)dm->data; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); ierr = DMSetUp(dm);CHKERRQ(ierr); ierr = PetscMalloc((com->nDM)*sizeof(ISLocalToGlobalMapping),ltogs);CHKERRQ(ierr); next = com->next; ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); /* loop over packed objects, handling one at at time */ cnt = 0; while (next) { ISLocalToGlobalMapping ltog; PetscMPIInt size; const PetscInt *suboff,*indices; Vec global; /* Get sub-DM global indices for each local dof */ ierr = DMGetLocalToGlobalMapping(next->dm,<og);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingGetSize(ltog,&n);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingGetIndices(ltog,&indices);CHKERRQ(ierr); ierr = PetscMalloc(n*sizeof(PetscInt),&idx);CHKERRQ(ierr); /* Get the offsets for the sub-DM global vector */ ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); ierr = VecGetOwnershipRanges(global,&suboff);CHKERRQ(ierr); ierr = MPI_Comm_size(((PetscObject)global)->comm,&size);CHKERRQ(ierr); /* Shift the sub-DM definition of the global space to the composite global space */ for (i=0; i<n; i++) { PetscInt subi = indices[i],lo = 0,hi = size,t; /* Binary search to find which rank owns subi */ while (hi-lo > 1) { t = lo + (hi-lo)/2; if (suboff[t] > subi) hi = t; else lo = t; } idx[i] = subi - suboff[lo] + next->grstarts[lo]; } ierr = ISLocalToGlobalMappingRestoreIndices(ltog,&indices);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,n,idx,PETSC_OWN_POINTER,&(*ltogs)[cnt]);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); next = next->next; cnt++; } PetscFunctionReturn(0); }
/*@C DMDAGetRay - Returns a vector on process zero that contains a row or column of the values in a DMDA vector Collective on DMDA Input Parameters: + da - the distributed array . vec - the vector . dir - Cartesian direction, either DMDA_X, DMDA_Y, or DMDA_Z - gp - global grid point number in this direction Output Parameters: + newvec - the new vector that can hold the values (size zero on all processes except process 0) - scatter - the VecScatter that will map from the original vector to the slice Level: advanced Notes: All processors that share the DMDA must call this with the same gp value .keywords: distributed array, get, processor subset @*/ PetscErrorCode DMDAGetRay(DM da,DMDADirection dir,PetscInt gp,Vec *newvec,VecScatter *scatter) { PetscMPIInt rank; DM_DA *dd = (DM_DA*)da->data; PetscErrorCode ierr; IS is; AO ao; Vec vec; PetscInt *indices,i,j; PetscFunctionBegin; if (dd->dim == 1) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Cannot get slice from 1d DMDA"); if (dd->dim == 3) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Cannot get slice from 3d DMDA"); ierr = DMDAGetAO(da,&ao);CHKERRQ(ierr); ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)da),&rank);CHKERRQ(ierr); if (!rank) { if (dir == DMDA_Y) { ierr = PetscMalloc(dd->w*dd->M*sizeof(PetscInt),&indices);CHKERRQ(ierr); indices[0] = gp*dd->M*dd->w; for (i=1; i<dd->M*dd->w; i++) indices[i] = indices[i-1] + 1; ierr = AOApplicationToPetsc(ao,dd->M*dd->w,indices);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,newvec);CHKERRQ(ierr); ierr = VecSetBlockSize(*newvec,dd->w);CHKERRQ(ierr); ierr = VecSetSizes(*newvec,dd->M*dd->w,PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetType(*newvec,VECSEQ);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_SELF,dd->w*dd->M,indices,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); } else if (dir == DMDA_X) { ierr = PetscMalloc(dd->w*dd->N*sizeof(PetscInt),&indices);CHKERRQ(ierr); indices[0] = dd->w*gp; for (j=1; j<dd->w; j++) indices[j] = indices[j-1] + 1; for (i=1; i<dd->N; i++) { indices[i*dd->w] = indices[i*dd->w-1] + dd->w*dd->M - dd->w + 1; for (j=1; j<dd->w; j++) indices[i*dd->w + j] = indices[i*dd->w + j - 1] + 1; } ierr = AOApplicationToPetsc(ao,dd->w*dd->N,indices);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,newvec);CHKERRQ(ierr); ierr = VecSetBlockSize(*newvec,dd->w);CHKERRQ(ierr); ierr = VecSetSizes(*newvec,dd->N*dd->w,PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetType(*newvec,VECSEQ);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_SELF,dd->w*dd->N,indices,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown DMDADirection"); } else { ierr = VecCreateSeq(PETSC_COMM_SELF,0,newvec);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_SELF,0,0,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); } ierr = DMGetGlobalVector(da,&vec);CHKERRQ(ierr); ierr = VecScatterCreate(vec,is,*newvec,NULL,scatter);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&vec);CHKERRQ(ierr); ierr = ISDestroy(&is);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DMCreateMatrix_MF(DM packer,Mat *A) { PetscErrorCode ierr; Vec t; PetscInt m; PetscFunctionBeginUser; ierr = DMGetGlobalVector(packer,&t);CHKERRQ(ierr); ierr = VecGetLocalSize(t,&m);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(packer,&t);CHKERRQ(ierr); ierr = MatCreateMFFD(PETSC_COMM_WORLD,m,m,PETSC_DETERMINE,PETSC_DETERMINE,A);CHKERRQ(ierr); ierr = MatSetUp(*A);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode CreatePressureNullSpace(DM dm, AppCtx *user, MatNullSpace *nullSpace) { Vec vec, localVec; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = DMGetGlobalVector(dm, &vec);CHKERRQ(ierr); ierr = DMGetLocalVector(dm, &localVec);CHKERRQ(ierr); ierr = VecSet(vec, 0.0);CHKERRQ(ierr); /* Put a constant in for all pressures Could change this to project the constant function onto the pressure space (when that is finished) */ { PetscSection section; PetscInt pStart, pEnd, p; PetscScalar *a; ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); ierr = VecGetArray(localVec, &a);CHKERRQ(ierr); for (p = pStart; p < pEnd; ++p) { PetscInt fDim, off, d; ierr = PetscSectionGetFieldDof(section, p, 1, &fDim);CHKERRQ(ierr); ierr = PetscSectionGetFieldOffset(section, p, 1, &off);CHKERRQ(ierr); for (d = 0; d < fDim; ++d) a[off+d] = 1.0; } ierr = VecRestoreArray(localVec, &a);CHKERRQ(ierr); } ierr = DMLocalToGlobalBegin(dm, localVec, INSERT_VALUES, vec);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(dm, localVec, INSERT_VALUES, vec);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm, &localVec);CHKERRQ(ierr); ierr = VecNormalize(vec, NULL);CHKERRQ(ierr); if (user->debug) { ierr = PetscPrintf(PetscObjectComm((PetscObject)dm), "Pressure Null Space\n");CHKERRQ(ierr); ierr = VecView(vec, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)dm), PETSC_FALSE, 1, &vec, nullSpace);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dm, &vec);CHKERRQ(ierr); /* New style for field null spaces */ { PetscObject pressure; MatNullSpace nullSpacePres; ierr = DMGetField(dm, 1, &pressure);CHKERRQ(ierr); ierr = MatNullSpaceCreate(PetscObjectComm(pressure), PETSC_TRUE, 0, NULL, &nullSpacePres);CHKERRQ(ierr); ierr = PetscObjectCompose(pressure, "nullspace", (PetscObject) nullSpacePres);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&nullSpacePres);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode DMCreateFieldDecomposition_DA(DM dm, PetscInt *len,char ***namelist, IS **islist, DM** dmlist) { PetscInt i; PetscErrorCode ierr; DM_DA *dd = (DM_DA*)dm->data; PetscInt dof = dd->w; PetscFunctionBegin; if(len) *len = dof; if (islist) { Vec v; PetscInt rstart,n; ierr = DMGetGlobalVector(dm,&v);CHKERRQ(ierr); ierr = VecGetOwnershipRange(v,&rstart,PETSC_NULL);CHKERRQ(ierr); ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dm,&v);CHKERRQ(ierr); ierr = PetscMalloc(dof*sizeof(IS),islist);CHKERRQ(ierr); for (i=0; i<dof; i++) { ierr = ISCreateStride(((PetscObject)dm)->comm,n/dof,rstart+i,dof,&(*islist)[i]);CHKERRQ(ierr); } } if (namelist) { ierr = PetscMalloc(dof*sizeof(const char *), namelist);CHKERRQ(ierr); if (dd->fieldname) { for (i=0; i<dof; i++) { ierr = PetscStrallocpy(dd->fieldname[i],&(*namelist)[i]);CHKERRQ(ierr); } } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Currently DMDA must have fieldnames"); } if (dmlist) { DM da; ierr = DMDACreate(((PetscObject)dm)->comm, &da);CHKERRQ(ierr); ierr = DMDASetDim(da, dd->dim);CHKERRQ(ierr); ierr = DMDASetSizes(da, dd->M, dd->N, dd->P);CHKERRQ(ierr); ierr = DMDASetNumProcs(da, dd->m, dd->n, dd->p);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da, dd->bx, dd->by, dd->bz);CHKERRQ(ierr); ierr = DMDASetDof(da, 1);CHKERRQ(ierr); ierr = DMDASetStencilType(da, dd->stencil_type);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da, dd->s);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = PetscMalloc(dof*sizeof(DM),dmlist);CHKERRQ(ierr); for (i=0; i<dof-1; i++) {ierr = PetscObjectReference((PetscObject)da);CHKERRQ(ierr);} for (i=0; i<dof; i++) (*dmlist)[i] = da; } PetscFunctionReturn(0); }
/* FormFunctionLocal - Evaluates nonlinear residual, F(x) on local process patch */ PetscErrorCode FormFunctionLocal(DMDALocalInfo *info, Field *u, Field *f, AppCtx *user) { Vec L; PetscReal phi = user->phi; PetscReal dt = user->dt; PetscReal dx = 1.0/(PetscReal)(info->mx-1); PetscReal alpha = 2.0; PetscReal beta = 2.0; PetscReal kappaWet = user->kappaWet; PetscReal kappaNoWet = user->kappaNoWet; Field *uold; PetscScalar *Kappa; PetscInt i; PetscErrorCode ierr; PetscFunctionBegin; ierr = DMGetGlobalVector(user->cda, &L);CHKERRQ(ierr); ierr = DMDAVecGetArray(info->da, user->uold, &uold);CHKERRQ(ierr); ierr = DMDAVecGetArray(user->cda, user->Kappa, &Kappa);CHKERRQ(ierr); /* Compute residual over the locally owned part of the grid */ for(i = info->xs; i < info->xs+info->xm; ++i) { if (i == 0) { f[i].s = u[i].s - user->sl; f[i].v = u[i].v - user->vl; f[i].p = u[i].p - user->pl; } else { PetscScalar K = 2*dx/(dx/Kappa[i] + dx/Kappa[i-1]); PetscReal lambdaWet = kappaWet*pow(u[i].s, alpha); PetscReal lambda = lambdaWet + kappaNoWet*pow(1-u[i].s, beta); PetscReal lambdaWetL = kappaWet*pow(u[i-1].s, alpha); PetscReal lambdaL = lambdaWetL + kappaNoWet*pow(1-u[i-1].s, beta); f[i].s = phi*(u[i].s - uold[i].s) + (dt/dx)*((lambdaWet/lambda)*u[i].v - (lambdaWetL/lambdaL)*u[i-1].v); f[i].v = u[i].v + K*lambda*(u[i].p - u[i-1].p)/dx; //pxx = (2.0*u[i].p - u[i-1].p - u[i+1].p)/dx; f[i].p = u[i].v - u[i-1].v; } } ierr = DMDAVecRestoreArray(info->da, user->uold, &uold);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(user->cda, user->Kappa, &Kappa);CHKERRQ(ierr); /* ierr = PetscLogFlops(11.0*info->ym*info->xm);CHKERRQ(ierr); */ ierr = DMRestoreGlobalVector(user->cda, &L);CHKERRQ(ierr); PetscFunctionReturn(0); }
EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "VecView_DMComposite" PetscErrorCode VecView_DMComposite(Vec gvec,PetscViewer viewer) { DM dm; PetscErrorCode ierr; struct DMCompositeLink *next; PetscBool isdraw; DM_Composite *com; PetscFunctionBegin; ierr = VecGetDM(gvec, &dm);CHKERRQ(ierr); if (!dm) SETERRQ(((PetscObject)gvec)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMComposite"); com = (DM_Composite*)dm->data; next = com->next; ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); if (!isdraw) { /* do I really want to call this? */ ierr = VecView_MPI(gvec,viewer);CHKERRQ(ierr); } else { PetscInt cnt = 0; /* loop over packed objects, handling one at at time */ while (next) { Vec vec; PetscScalar *array; PetscInt bs; /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */ ierr = DMGetGlobalVector(next->dm,&vec);CHKERRQ(ierr); ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); ierr = VecPlaceArray(vec,array+next->rstart);CHKERRQ(ierr); ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); ierr = VecView(vec,viewer);CHKERRQ(ierr); ierr = VecGetBlockSize(vec,&bs);CHKERRQ(ierr); ierr = VecResetArray(vec);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(next->dm,&vec);CHKERRQ(ierr); ierr = PetscViewerDrawBaseAdd(viewer,bs);CHKERRQ(ierr); cnt += bs; next = next->next; } ierr = PetscViewerDrawBaseAdd(viewer,-cnt);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@C SNESSetWorkVecs - Gets a number of work vectors. Input Parameters: . snes - the SNES context . nw - number of work vectors to allocate Level: developer Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations @*/ PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw) { DM dm; Vec v; PetscErrorCode ierr; PetscFunctionBegin; if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} snes->nwork = nw; ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr); ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc, char **argv) { AppCtx user; /* user-defined work context */ Vec u; PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL, help);CHKERRQ(ierr); ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr); ierr = CreateMesh(PETSC_COMM_WORLD, &user, &user.dm);CHKERRQ(ierr); ierr = SetupElement(user.dm, &user);CHKERRQ(ierr); ierr = SetupSection(user.dm, &user);CHKERRQ(ierr); ierr = DMGetGlobalVector(user.dm, &u);CHKERRQ(ierr); ierr = CheckFunctions(user.dm, user.porder, u, &user);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(user.dm, &u);CHKERRQ(ierr); ierr = PetscFEDestroy(&user.fe);CHKERRQ(ierr); ierr = DMDestroy(&user.dm);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
static PetscErrorCode TestFunctionProjection(DM dm, DM auxdm, DMLabel label, Vec la, const char name[], AppCtx *user) { PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *); Vec x, lx; PetscInt Nf, f; PetscInt val[1] = {1}; char lname[PETSC_MAX_PATH_LEN]; PetscErrorCode ierr; PetscFunctionBeginUser; if (auxdm) { ierr = PetscObjectCompose((PetscObject) dm, "dmAux", (PetscObject) auxdm);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "A", (PetscObject) la);CHKERRQ(ierr); } ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); ierr = PetscMalloc1(Nf, &funcs);CHKERRQ(ierr); for (f = 0; f < Nf; ++f) funcs[f] = linear; ierr = DMGetGlobalVector(dm, &x);CHKERRQ(ierr); ierr = PetscStrcpy(lname, "Function ");CHKERRQ(ierr); ierr = PetscStrcat(lname, name);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, lname);CHKERRQ(ierr); if (!label) {ierr = DMProjectFunction(dm, 0.0, funcs, NULL, INSERT_VALUES, x);CHKERRQ(ierr);} else {ierr = DMProjectFunctionLabel(dm, 0.0, label, 1, val, 0, NULL, funcs, NULL, INSERT_VALUES, x);CHKERRQ(ierr);} ierr = VecViewFromOptions(x, NULL, "-func_view");CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dm, &x);CHKERRQ(ierr); ierr = DMGetLocalVector(dm, &lx);CHKERRQ(ierr); ierr = PetscStrcpy(lname, "Local Function ");CHKERRQ(ierr); ierr = PetscStrcat(lname, name);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) lx, lname);CHKERRQ(ierr); if (!label) {ierr = DMProjectFunctionLocal(dm, 0.0, funcs, NULL, INSERT_VALUES, lx);CHKERRQ(ierr);} else {ierr = DMProjectFunctionLabelLocal(dm, 0.0, label, 1, val, 0, NULL, funcs, NULL, INSERT_VALUES, lx);CHKERRQ(ierr);} ierr = VecViewFromOptions(lx, NULL, "-local_func_view");CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm, &lx);CHKERRQ(ierr); ierr = PetscFree(funcs);CHKERRQ(ierr); if (auxdm) { ierr = PetscObjectCompose((PetscObject) dm, "dmAux", NULL);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "A", NULL);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@C DMCompositeAddDM - adds a DM vector to a DMComposite Collective on DMComposite Input Parameter: + dm - the packer object - dm - the DM object, if the DM is a da you will need to caste it with a (DM) Level: advanced .seealso DMDestroy(), DMCompositeGather(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() @*/ PetscErrorCode DMCompositeAddDM(DM dmc,DM dm) { PetscErrorCode ierr; PetscInt n,nlocal; struct DMCompositeLink *mine,*next; Vec global,local; DM_Composite *com = (DM_Composite*)dmc->data; PetscFunctionBegin; PetscValidHeaderSpecific(dmc,DM_CLASSID,1); PetscValidHeaderSpecific(dm,DM_CLASSID,2); next = com->next; if (com->setup) SETERRQ(((PetscObject)dmc)->comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot add a DM once you have used the DMComposite"); /* create new link */ ierr = PetscNew(struct DMCompositeLink,&mine);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); ierr = DMGetGlobalVector(dm,&global);CHKERRQ(ierr); ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dm,&global);CHKERRQ(ierr); ierr = DMGetLocalVector(dm,&local);CHKERRQ(ierr); ierr = VecGetSize(local,&nlocal);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm,&local);CHKERRQ(ierr); mine->n = n; mine->nlocal = nlocal; mine->dm = dm; mine->next = PETSC_NULL; com->n += n; /* add to end of list */ if (!next) { com->next = mine; } else { while (next->next) next = next->next; next->next = mine; } com->nDM++; com->nmine++; PetscFunctionReturn(0); }
PetscErrorCode OpGetMat(Op op,DM dm,Mat *shell) { PetscErrorCode ierr; Mat A; Vec U; PetscInt m; Mat_Op *ctx; PetscFunctionBegin; ierr = DMGetGlobalVector(dm,&U);CHKERRQ(ierr); ierr = VecGetLocalSize(U,&m);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dm,&U);CHKERRQ(ierr); ierr = PetscMalloc1(1,&ctx);CHKERRQ(ierr); // Danger: no reference counting ctx->op = op; ctx->dm = dm; ierr = MatCreateShell(PetscObjectComm((PetscObject)dm),m,m,PETSC_DETERMINE,PETSC_DETERMINE,ctx,&A);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_DESTROY,(void(*)(void))MatDestroy_Op);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)(void))MatMult_Op);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_GET_DIAGONAL,(void(*)(void))MatGetDiagonal_Op);CHKERRQ(ierr); *shell = A; PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscInt M = -10,N = -8; PetscErrorCode ierr; PetscBool flg = PETSC_FALSE; DM da; Vec global1,global2,global3; DMDABoundaryType bx = DMDA_BOUNDARY_NONE,by = DMDA_BOUNDARY_NONE; DMDAStencilType stype = DMDA_STENCIL_BOX; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscOptionsGetBool(PETSC_NULL,"-star_stencil",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) stype = DMDA_STENCIL_STAR; /* Create distributed array and get vectors */ ierr = DMDACreate2d(PETSC_COMM_WORLD,bx,by,stype,M,N,PETSC_DECIDE,PETSC_DECIDE,1,1,PETSC_NULL,PETSC_NULL,&da);CHKERRQ(ierr); ierr = DMGetGlobalVector(da,&global1);CHKERRQ(ierr); ierr = DMGetGlobalVector(da,&global2);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&global1);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&global2);CHKERRQ(ierr); ierr = DMGetGlobalVector(da,&global1);CHKERRQ(ierr); ierr = DMGetGlobalVector(da,&global3);CHKERRQ(ierr); ierr = DMGetGlobalVector(da,&global2);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&global1);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&global3);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&global2);CHKERRQ(ierr); ierr = DMGetGlobalVector(da,&global1);CHKERRQ(ierr); ierr = DMGetGlobalVector(da,&global3);CHKERRQ(ierr); ierr = DMGetGlobalVector(da,&global2);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&global1);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&global3);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&global2);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc, char **argv) { DM dm; Vec u; AppCtx ctx; PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr; ierr = ProcessOptions(PETSC_COMM_WORLD, &ctx);CHKERRQ(ierr); ierr = DMPlexCreateSphereMesh(PETSC_COMM_WORLD, ctx.dim, ctx.simplex, &dm);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) dm, "Sphere");CHKERRQ(ierr); ierr = DMSetFromOptions(dm);CHKERRQ(ierr); ierr = ProjectToUnitSphere(dm);CHKERRQ(ierr); ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr); ierr = SetupSection(dm);CHKERRQ(ierr); ierr = DMGetGlobalVector(dm, &u);CHKERRQ(ierr); ierr = VecSet(u, 2);CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-vec_view");CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dm, &u);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
/*@C DMCompositeGather - Gathers into a global packed vector from its individual local vectors Collective on DMComposite Input Parameter: + dm - the packer object . gvec - the global vector - Vec ... - the individual sequential vectors, PETSC_NULL for any that are not needed Level: advanced .seealso DMDestroy(), DMCompositeAddDM(), DMCreateGlobalVector(), DMCompositeScatter(), DMCompositeCreate(), DMCompositeGetISLocalToGlobalMappings(), DMCompositeGetAccess(), DMCompositeGetLocalVectors(), DMCompositeRestoreLocalVectors(), DMCompositeGetEntries() @*/ PetscErrorCode DMCompositeGather(DM dm,Vec gvec,InsertMode imode,...) { va_list Argp; PetscErrorCode ierr; struct DMCompositeLink *next; DM_Composite *com = (DM_Composite*)dm->data; PetscInt cnt; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); PetscValidHeaderSpecific(gvec,VEC_CLASSID,2); if (!com->setup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } /* loop over packed objects, handling one at at time */ va_start(Argp,imode); for (cnt=3,next=com->next; next; cnt++,next=next->next) { Vec local; local = va_arg(Argp, Vec); if (local) { PetscScalar *array; Vec global; PetscValidHeaderSpecific(local,VEC_CLASSID,cnt); ierr = DMGetGlobalVector(next->dm,&global);CHKERRQ(ierr); ierr = VecGetArray(gvec,&array);CHKERRQ(ierr); ierr = VecPlaceArray(global,array+next->rstart);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(next->dm,local,imode,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(next->dm,local,imode,global);CHKERRQ(ierr); ierr = VecRestoreArray(gvec,&array);CHKERRQ(ierr); ierr = VecResetArray(global);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(next->dm,&global);CHKERRQ(ierr); } } va_end(Argp); PetscFunctionReturn(0); }
void PETSC_STDCALL dmrestoreglobalvector_(DM dm,Vec* g, int *__ierr ){ *__ierr = DMRestoreGlobalVector( (DM)PetscToPointer((dm) ),g); }
/* Notice that this requires the previous momentum solution. The element stiffness matrix for the identity in linear elements is 1 /2 1 1\ - |1 2 1| 12 \1 1 2/ no matter what the shape of the triangle. */ PetscErrorCode TaylorGalerkinStepIIMassEnergy(DM da, UserContext *user) { MPI_Comm comm; Mat mat; Vec rhs_m, rhs_e; PetscScalar identity[9] = {0.16666666667, 0.08333333333, 0.08333333333, 0.08333333333, 0.16666666667, 0.08333333333, 0.08333333333, 0.08333333333, 0.16666666667}; PetscScalar *u_n, *v_n, *p_n, *t_n, *mu_n, *kappa_n; PetscScalar *rho_n, *rho_u_n, *rho_v_n, *rho_e_n; PetscScalar *u_phi, *v_phi; PetscScalar *rho_u_np1, *rho_v_np1; PetscInt idx[3]; PetscScalar psi_x[3], psi_y[3]; PetscScalar values_m[3]; PetscScalar values_e[3]; PetscScalar phi = user->phi; PetscScalar mu, kappa, tau_xx, tau_xy, tau_yy, q_x, q_y; PetscReal hx, hy, area; KSP ksp; const PetscInt *necon; PetscInt j, k, e, ne, nc, mx, my; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = PetscObjectGetComm((PetscObject) da, &comm);CHKERRQ(ierr); ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(da, &mat);CHKERRQ(ierr); ierr = MatSetOption(mat,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &rhs_m);CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &rhs_e);CHKERRQ(ierr); ierr = KSPCreate(comm, &ksp);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = DMDAGetInfo(da, 0, &mx, &my, 0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); hx = 1.0 / (PetscReal)(mx-1); hy = 1.0 / (PetscReal)(my-1); area = 0.5*hx*hy; ierr = VecGetArray(user->sol_n.u, &u_n);CHKERRQ(ierr); ierr = VecGetArray(user->sol_n.v, &v_n);CHKERRQ(ierr); ierr = VecGetArray(user->sol_n.p, &p_n);CHKERRQ(ierr); ierr = VecGetArray(user->sol_n.t, &t_n);CHKERRQ(ierr); ierr = VecGetArray(user->mu, &mu_n);CHKERRQ(ierr); ierr = VecGetArray(user->kappa, &kappa_n);CHKERRQ(ierr); ierr = VecGetArray(user->sol_n.rho, &rho_n);CHKERRQ(ierr); ierr = VecGetArray(user->sol_n.rho_u, &rho_u_n);CHKERRQ(ierr); ierr = VecGetArray(user->sol_n.rho_v, &rho_v_n);CHKERRQ(ierr); ierr = VecGetArray(user->sol_n.rho_e, &rho_e_n);CHKERRQ(ierr); ierr = VecGetArray(user->sol_phi.u, &u_phi);CHKERRQ(ierr); ierr = VecGetArray(user->sol_phi.v, &v_phi);CHKERRQ(ierr); ierr = VecGetArray(user->sol_np1.rho_u, &rho_u_np1);CHKERRQ(ierr); ierr = VecGetArray(user->sol_np1.rho_v, &rho_v_np1);CHKERRQ(ierr); ierr = DMDAGetElements(da, &ne, &nc, &necon);CHKERRQ(ierr); for (e = 0; e < ne; e++) { for (j = 0; j < 3; j++) { idx[j] = necon[3*e+j]; values_m[j] = 0.0; values_e[j] = 0.0; } /* Get basis function deriatives (we need the orientation of the element here) */ if (idx[1] > idx[0]) { psi_x[0] = -hy; psi_x[1] = hy; psi_x[2] = 0.0; psi_y[0] = -hx; psi_y[1] = 0.0; psi_y[2] = hx; } else { psi_x[0] = hy; psi_x[1] = -hy; psi_x[2] = 0.0; psi_y[0] = hx; psi_y[1] = 0.0; psi_y[2] = -hx; } /* <\nabla\psi, F^*>: Divergence of the predicted convective fluxes */ for (j = 0; j < 3; j++) { values_m[j] += (psi_x[j]*(phi*rho_u_np1[idx[j]] + rho_u_n[idx[j]]) + psi_y[j]*(rho_v_np1[idx[j]] + rho_v_n[idx[j]]))/3.0; values_e[j] += values_m[j]*((rho_e_n[idx[j]] + p_n[idx[j]]) / rho_n[idx[j]]); } /* -<\nabla\psi, F^n_v>: Divergence of the viscous fluxes */ for (j = 0; j < 3; j++) { /* \tau_{xx} = 2/3 \mu(T) (2 {\partial u\over\partial x} - {\partial v\over\partial y}) */ /* \tau_{xy} = \mu(T) ( {\partial u\over\partial y} + {\partial v\over\partial x}) */ /* \tau_{yy} = 2/3 \mu(T) (2 {\partial v\over\partial y} - {\partial u\over\partial x}) */ /* q_x = -\kappa(T) {\partial T\over\partial x} */ /* q_y = -\kappa(T) {\partial T\over\partial y} */ /* above code commeted out - causing ininitialized variables. */ q_x =0; q_y =0; mu = 0.0; kappa = 0.0; tau_xx = 0.0; tau_xy = 0.0; tau_yy = 0.0; for (k = 0; k < 3; k++) { mu += mu_n[idx[k]]; kappa += kappa_n[idx[k]]; tau_xx += 2.0*psi_x[k]*u_n[idx[k]] - psi_y[k]*v_n[idx[k]]; tau_xy += psi_y[k]*u_n[idx[k]] + psi_x[k]*v_n[idx[k]]; tau_yy += 2.0*psi_y[k]*v_n[idx[k]] - psi_x[k]*u_n[idx[k]]; q_x += psi_x[k]*t_n[idx[k]]; q_y += psi_y[k]*t_n[idx[k]]; } mu /= 3.0; kappa /= 3.0; tau_xx *= (2.0/3.0)*mu; tau_xy *= mu; tau_yy *= (2.0/3.0)*mu; values_e[j] -= area*(psi_x[j]*(u_phi[e]*tau_xx + v_phi[e]*tau_xy + q_x) + psi_y[j]*(u_phi[e]*tau_xy + v_phi[e]*tau_yy + q_y)); } /* Accumulate to global structures */ ierr = VecSetValuesLocal(rhs_m, 3, idx, values_m, ADD_VALUES);CHKERRQ(ierr); ierr = VecSetValuesLocal(rhs_e, 3, idx, values_e, ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValuesLocal(mat, 3, idx, 3, idx, identity, ADD_VALUES);CHKERRQ(ierr); } ierr = DMDARestoreElements(da, &ne, &nc, &necon);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_n.u, &u_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_n.v, &v_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_n.p, &p_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_n.t, &t_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->mu, &mu_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->kappa, &kappa_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_n.rho, &rho_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_n.rho_u, &rho_u_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_n.rho_v, &rho_v_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_n.rho_e, &rho_e_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_phi.u, &u_phi);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_phi.v, &v_phi);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_np1.rho_u, &rho_u_np1);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_np1.rho_v, &rho_v_np1);CHKERRQ(ierr); ierr = VecAssemblyBegin(rhs_m);CHKERRQ(ierr); ierr = VecAssemblyBegin(rhs_e);CHKERRQ(ierr); ierr = MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecAssemblyEnd(rhs_m);CHKERRQ(ierr); ierr = VecAssemblyEnd(rhs_e);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecScale(rhs_m, user->dt);CHKERRQ(ierr); ierr = VecScale(rhs_e, user->dt);CHKERRQ(ierr); ierr = KSPSetOperators(ksp, mat, mat, DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = KSPSolve(ksp, rhs_m, user->sol_np1.rho);CHKERRQ(ierr); ierr = KSPSolve(ksp, rhs_e, user->sol_np1.rho_e);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da, &rhs_m);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da, &rhs_e);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* The element stiffness matrix for the identity in linear elements is 1 /2 1 1\ - |1 2 1| 12 \1 1 2/ no matter what the shape of the triangle. */ PetscErrorCode TaylorGalerkinStepIIMomentum(DM da, UserContext *user) { MPI_Comm comm; KSP ksp; Mat mat; Vec rhs_u, rhs_v; PetscScalar identity[9] = {0.16666666667, 0.08333333333, 0.08333333333, 0.08333333333, 0.16666666667, 0.08333333333, 0.08333333333, 0.08333333333, 0.16666666667}; PetscScalar *u_n, *v_n, *mu_n; PetscScalar *u_phi, *v_phi; PetscScalar *rho_u_phi, *rho_v_phi; PetscInt idx[3]; PetscScalar values_u[3]; PetscScalar values_v[3]; PetscScalar psi_x[3], psi_y[3]; PetscScalar mu, tau_xx, tau_xy, tau_yy; PetscReal hx, hy, area; const PetscInt *necon; PetscInt j, k, e, ne, nc, mx, my; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = PetscObjectGetComm((PetscObject) da, &comm);CHKERRQ(ierr); ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(da, &mat);CHKERRQ(ierr); ierr = MatSetOption(mat,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &rhs_u);CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &rhs_v);CHKERRQ(ierr); ierr = KSPCreate(comm, &ksp);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = DMDAGetInfo(da, 0, &mx, &my, 0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); hx = 1.0 / (PetscReal)(mx-1); hy = 1.0 / (PetscReal)(my-1); area = 0.5*hx*hy; ierr = VecGetArray(user->sol_n.u, &u_n);CHKERRQ(ierr); ierr = VecGetArray(user->sol_n.v, &v_n);CHKERRQ(ierr); ierr = VecGetArray(user->mu, &mu_n);CHKERRQ(ierr); ierr = VecGetArray(user->sol_phi.u, &u_phi);CHKERRQ(ierr); ierr = VecGetArray(user->sol_phi.v, &v_phi);CHKERRQ(ierr); ierr = VecGetArray(user->sol_phi.rho_u, &rho_u_phi);CHKERRQ(ierr); ierr = VecGetArray(user->sol_phi.rho_v, &rho_v_phi);CHKERRQ(ierr); ierr = DMDAGetElements(da, &ne, &nc, &necon);CHKERRQ(ierr); for (e = 0; e < ne; e++) { for (j = 0; j < 3; j++) { idx[j] = necon[3*e+j]; values_u[j] = 0.0; values_v[j] = 0.0; } /* Get basis function deriatives (we need the orientation of the element here) */ if (idx[1] > idx[0]) { psi_x[0] = -hy; psi_x[1] = hy; psi_x[2] = 0.0; psi_y[0] = -hx; psi_y[1] = 0.0; psi_y[2] = hx; } else { psi_x[0] = hy; psi_x[1] = -hy; psi_x[2] = 0.0; psi_y[0] = hx; psi_y[1] = 0.0; psi_y[2] = -hx; } /* <\nabla\psi, F^{n+\phi}_e>: Divergence of the element-averaged convective fluxes */ for (j = 0; j < 3; j++) { values_u[j] += psi_x[j]*rho_u_phi[e]*u_phi[e] + psi_y[j]*rho_u_phi[e]*v_phi[e]; values_v[j] += psi_x[j]*rho_v_phi[e]*u_phi[e] + psi_y[j]*rho_v_phi[e]*v_phi[e]; } /* -<\nabla\psi, F^n_v>: Divergence of the viscous fluxes */ for (j = 0; j < 3; j++) { /* \tau_{xx} = 2/3 \mu(T) (2 {\partial u\over\partial x} - {\partial v\over\partial y}) */ /* \tau_{xy} = \mu(T) ( {\partial u\over\partial y} + {\partial v\over\partial x}) */ /* \tau_{yy} = 2/3 \mu(T) (2 {\partial v\over\partial y} - {\partial u\over\partial x}) */ mu = 0.0; tau_xx = 0.0; tau_xy = 0.0; tau_yy = 0.0; for (k = 0; k < 3; k++) { mu += mu_n[idx[k]]; tau_xx += 2.0*psi_x[k]*u_n[idx[k]] - psi_y[k]*v_n[idx[k]]; tau_xy += psi_y[k]*u_n[idx[k]] + psi_x[k]*v_n[idx[k]]; tau_yy += 2.0*psi_y[k]*v_n[idx[k]] - psi_x[k]*u_n[idx[k]]; } mu /= 3.0; tau_xx *= (2.0/3.0)*mu; tau_xy *= mu; tau_yy *= (2.0/3.0)*mu; values_u[j] -= area*(psi_x[j]*tau_xx + psi_y[j]*tau_xy); values_v[j] -= area*(psi_x[j]*tau_xy + psi_y[j]*tau_yy); } /* Accumulate to global structures */ ierr = VecSetValuesLocal(rhs_u, 3, idx, values_u, ADD_VALUES);CHKERRQ(ierr); ierr = VecSetValuesLocal(rhs_v, 3, idx, values_v, ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValuesLocal(mat, 3, idx, 3, idx, identity, ADD_VALUES);CHKERRQ(ierr); } ierr = DMDARestoreElements(da, &ne, &nc, &necon);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_n.u, &u_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_n.v, &v_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->mu, &mu_n);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_phi.u, &u_phi);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_phi.v, &v_phi);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_phi.rho_u, &rho_u_phi);CHKERRQ(ierr); ierr = VecRestoreArray(user->sol_phi.rho_v, &rho_v_phi);CHKERRQ(ierr); ierr = VecAssemblyBegin(rhs_u);CHKERRQ(ierr); ierr = VecAssemblyBegin(rhs_v);CHKERRQ(ierr); ierr = MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecAssemblyEnd(rhs_u);CHKERRQ(ierr); ierr = VecAssemblyEnd(rhs_v);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecScale(rhs_u,user->dt);CHKERRQ(ierr); ierr = VecScale(rhs_v,user->dt);CHKERRQ(ierr); ierr = KSPSetOperators(ksp, mat, mat, DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = KSPSolve(ksp, rhs_u, user->sol_np1.rho_u);CHKERRQ(ierr); ierr = KSPSolve(ksp, rhs_v, user->sol_np1.rho_v);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da, &rhs_u);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da, &rhs_v);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; DM da,*subda; PetscInt i,dim=3; PetscMPIInt size,rank; Vec v; Vec slvec,sgvec; IS *ois,*iis; VecScatter oscata; VecScatter *iscat,*oscat,*gscat; DMDALocalInfo info; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-dim",&dim,NULL);CHKERRQ(ierr); /* Create distributed array and get vectors */ ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); if (dim == 2) { ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,3,1,NULL,NULL,&da);CHKERRQ(ierr); } else if (dim == 3) { ierr = DMDACreate3d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-4,-4,-4,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,3,1,NULL,NULL,NULL,&da);CHKERRQ(ierr); } ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); ierr = DMCreateDomainDecomposition(da,NULL,NULL,&iis,&ois,&subda);CHKERRQ(ierr); ierr = DMCreateDomainDecompositionScatters(da,1,subda,&iscat,&oscat,&gscat);CHKERRQ(ierr); { DMDALocalInfo subinfo; MatStencil lower,upper; IS patchis,subpatchis; Vec smallvec; Vec largevec; VecScatter patchscat; ierr = DMDAGetLocalInfo(subda[0],&subinfo);CHKERRQ(ierr); lower.i = info.xs; lower.j = info.ys; lower.k = info.zs; upper.i = info.xs+info.xm; upper.j = info.ys+info.ym; upper.k = info.zs+info.zm; /* test the patch IS as a thing to scatter to/from */ ierr = DMDACreatePatchIS(da,&lower,&upper,&patchis);CHKERRQ(ierr); ierr = DMGetGlobalVector(da,&largevec);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,&smallvec);CHKERRQ(ierr); ierr = VecSetSizes(smallvec,info.dof*(upper.i - lower.i)*(upper.j - lower.j)*(upper.k - lower.k),PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(smallvec);CHKERRQ(ierr); ierr = VecScatterCreate(smallvec,NULL,largevec,patchis,&patchscat);CHKERRQ(ierr); ierr = FillLocalSubdomain(subda[0],smallvec);CHKERRQ(ierr); ierr = VecSet(largevec,0);CHKERRQ(ierr); ierr = VecScatterBegin(patchscat,smallvec,largevec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(patchscat,smallvec,largevec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); for (i = 0; i < size; i++) { if (i == rank) { ierr = ISView(patchis,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = VecScatterView(patchscat,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = VecView(smallvec,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr); } ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr); ierr = VecView(largevec,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecDestroy(&smallvec);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&largevec);CHKERRQ(ierr); ierr = ISDestroy(&patchis);CHKERRQ(ierr); ierr = VecScatterDestroy(&patchscat);CHKERRQ(ierr); } /* view the various parts */ { for (i = 0; i < size; i++) { if (i == rank) { ierr = PetscPrintf(PETSC_COMM_SELF,"Processor %d: \n",i);CHKERRQ(ierr); ierr = DMView(subda[0],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr); } ierr = DMGetLocalVector(subda[0],&slvec);CHKERRQ(ierr); ierr = DMGetGlobalVector(subda[0],&sgvec);CHKERRQ(ierr); ierr = DMGetGlobalVector(da,&v);CHKERRQ(ierr); /* test filling outer between the big DM and the small ones with the IS scatter*/ ierr = VecScatterCreate(v,ois[0],sgvec,NULL,&oscata);CHKERRQ(ierr); ierr = FillLocalSubdomain(subda[0],sgvec);CHKERRQ(ierr); ierr = VecScatterBegin(oscata,sgvec,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(oscata,sgvec,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); /* test the local-to-local scatter */ /* fill up the local subdomain and then add them together */ ierr = FillLocalSubdomain(da,v);CHKERRQ(ierr); ierr = VecScatterBegin(gscat[0],v,slvec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(gscat[0],v,slvec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecView(v,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* test ghost scattering backwards */ ierr = VecSet(v,0);CHKERRQ(ierr); ierr = VecScatterBegin(gscat[0],slvec,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(gscat[0],slvec,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecView(v,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* test overlap scattering backwards */ ierr = DMLocalToGlobalBegin(subda[0],slvec,ADD_VALUES,sgvec);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(subda[0],slvec,ADD_VALUES,sgvec);CHKERRQ(ierr); ierr = VecSet(v,0);CHKERRQ(ierr); ierr = VecScatterBegin(oscat[0],sgvec,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(oscat[0],sgvec,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecView(v,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* test interior scattering backwards */ ierr = VecSet(v,0);CHKERRQ(ierr); ierr = VecScatterBegin(iscat[0],sgvec,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(iscat[0],sgvec,v,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecView(v,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* test matrix allocation */ for (i = 0; i < size; i++) { if (i == rank) { Mat m; ierr = PetscPrintf(PETSC_COMM_SELF,"Processor %d: \n",i);CHKERRQ(ierr); ierr = DMSetMatType(subda[0],MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(subda[0],&m);CHKERRQ(ierr); ierr = MatView(m,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = MatDestroy(&m);CHKERRQ(ierr); } ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr); } ierr = DMRestoreLocalVector(subda[0],&slvec);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(subda[0],&sgvec);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&v);CHKERRQ(ierr); } ierr = DMDestroy(&subda[0]);CHKERRQ(ierr); ierr = ISDestroy(&ois[0]);CHKERRQ(ierr); ierr = ISDestroy(&iis[0]);CHKERRQ(ierr); ierr = VecScatterDestroy(&iscat[0]);CHKERRQ(ierr); ierr = VecScatterDestroy(&oscat[0]);CHKERRQ(ierr); ierr = VecScatterDestroy(&gscat[0]);CHKERRQ(ierr); ierr = VecScatterDestroy(&oscata);CHKERRQ(ierr); ierr = PetscFree(iscat);CHKERRQ(ierr); ierr = PetscFree(oscat);CHKERRQ(ierr); ierr = PetscFree(gscat);CHKERRQ(ierr); ierr = PetscFree(oscata);CHKERRQ(ierr); ierr = PetscFree(subda);CHKERRQ(ierr); ierr = PetscFree(ois);CHKERRQ(ierr); ierr = PetscFree(iis);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); 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); }
/** Compute the gadient of the cell center gradient obtained by the least-square method */ PetscErrorCode GradientGradientJacobian(DM dm, Vec locX, PetscScalar elemMat[], void *ctx) { User user = (User) ctx; Physics phys = user->model->physics; PetscInt dof = phys->dof; const PetscScalar *facegeom, *cellgeom,*x; PetscErrorCode ierr; DM dmFace, dmCell; DM dmGrad = user->dmGrad; PetscInt fStart, fEnd, face, cStart; Vec Grad; /*here the localGradLimiter refers to the gradient that has been multiplied by the limiter function. The locGradLimiter is used to construct the uL and uR, and the locGrad is used to caculate the diffusion term*/ Vec TempVec; /*a temperal vec for the vector restore*/ PetscFunctionBeginUser; ierr = VecGetDM(user->facegeom,&dmFace);CHKERRQ(ierr); ierr = VecGetDM(user->cellgeom,&dmCell);CHKERRQ(ierr); ierr = DMGetGlobalVector(dmGrad,&Grad);CHKERRQ(ierr); ierr = VecZeroEntries(Grad);CHKERRQ(ierr); ierr = VecDuplicate(Grad, &TempVec);CHKERRQ(ierr); ierr = VecCopy(Grad, TempVec);CHKERRQ(ierr); ierr = VecGetArrayRead(user->facegeom,&facegeom);CHKERRQ(ierr); ierr = VecGetArrayRead(user->cellgeom,&cellgeom);CHKERRQ(ierr); ierr = VecGetArrayRead(locX,&x);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr); { PetscScalar *grad; ierr = VecGetArray(TempVec,&grad);CHKERRQ(ierr); /* Reconstruct gradients */ for (face=fStart; face<fEnd; face++) { const PetscInt *cells; const PetscScalar *cx[2]; const FaceGeom *fg; PetscScalar *cgrad[2]; PetscInt i,j; PetscBool ghost; ierr = IsExteriorGhostFace(dm,face,&ghost);CHKERRQ(ierr); if (ghost) continue; ierr = DMPlexGetSupport(dm,face,&cells);CHKERRQ(ierr); ierr = DMPlexPointLocalRead(dmFace,face,facegeom,&fg);CHKERRQ(ierr); for (i=0; i<2; i++) { ierr = DMPlexPointLocalRead(dm,cells[i],x,&cx[i]);CHKERRQ(ierr); ierr = DMPlexPointGlobalRef(dmGrad,cells[i],grad,&cgrad[i]);CHKERRQ(ierr); } for (i=0; i<dof; i++) { PetscScalar delta = cx[1][i] - cx[0][i]; for (j=0; j<DIM; j++) { if (cgrad[0]) cgrad[0][i*DIM+j] += fg->grad[0][j] * delta; if (cgrad[1]) cgrad[1][i*DIM+j] -= fg->grad[1][j] * delta; } } for (i=0; i<phys->dof; i++) { for (j=0; j<phys->dof; j++) { if(cells[0]<user->cEndInterior) elemMat[cells[0]*dof*dof + i*dof + j] -= cells[0]*1.0; if(cells[1]<user->cEndInterior) elemMat[cells[1]*dof*dof + i*dof + j] += cells[1]*1.2; } } } ierr = VecRestoreArray(TempVec,&grad);CHKERRQ(ierr); } ierr = DMRestoreGlobalVector(dmGrad,&Grad);CHKERRQ(ierr); ierr = VecRestoreArrayRead(user->facegeom,&facegeom);CHKERRQ(ierr); ierr = VecRestoreArrayRead(user->cellgeom,&cellgeom);CHKERRQ(ierr); ierr = VecRestoreArrayRead(locX,&x);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ComputeJacobian_LS(DM dm, Vec locX, PetscInt cell, PetscScalar CellValues[], void *ctx) { User user = (User) ctx; Physics phys = user->model->physics; PetscInt dof = phys->dof; const PetscScalar *facegeom, *cellgeom,*x; PetscErrorCode ierr; DM dmFace, dmCell; DM dmGrad = user->dmGrad; PetscInt fStart, fEnd, face, cStart; Vec locGrad, locGradLimiter, Grad; /*here the localGradLimiter refers to the gradient that has been multiplied by the limiter function. The locGradLimiter is used to construct the uL and uR, and the locGrad is used to caculate the diffusion term*/ Vec TempVec; /*a temperal vec for the vector restore*/ PetscFunctionBeginUser; ierr = VecGetDM(user->facegeom,&dmFace);CHKERRQ(ierr); ierr = VecGetDM(user->cellgeom,&dmCell);CHKERRQ(ierr); ierr = DMGetGlobalVector(dmGrad,&Grad);CHKERRQ(ierr); ierr = VecDuplicate(Grad, &TempVec);CHKERRQ(ierr); ierr = VecCopy(Grad, TempVec);CHKERRQ(ierr); /*Backup the original vector and use it to restore the value of dmGrad, because I do not want to change the values of the cell gradient*/ ierr = VecGetArrayRead(user->facegeom,&facegeom);CHKERRQ(ierr); ierr = VecGetArrayRead(user->cellgeom,&cellgeom);CHKERRQ(ierr); ierr = VecGetArrayRead(locX,&x);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr); { PetscScalar *grad; ierr = VecGetArray(Grad,&grad);CHKERRQ(ierr); /* Limit interior gradients. Using cell-based loop because it generalizes better to vector limiters. */ const PetscInt *faces; PetscInt numFaces,f; PetscReal *cellPhi; /* Scalar limiter applied to each component separately */ const PetscScalar *cx; const CellGeom *cg; PetscScalar *cgrad; PetscInt i; ierr = PetscMalloc(phys->dof*sizeof(PetscScalar),&cellPhi);CHKERRQ(ierr); ierr = DMPlexGetConeSize(dm,cell,&numFaces);CHKERRQ(ierr); ierr = DMPlexGetCone(dm,cell,&faces);CHKERRQ(ierr); ierr = DMPlexPointLocalRead(dm,cell,x,&cx);CHKERRQ(ierr); ierr = DMPlexPointLocalRead(dmCell,cell,cellgeom,&cg);CHKERRQ(ierr); ierr = DMPlexPointGlobalRef(dmGrad,cell,grad,&cgrad);CHKERRQ(ierr); /* Limiter will be minimum value over all neighbors */ for (i=0; i<dof; i++) { cellPhi[i] = PETSC_MAX_REAL; } for (f=0; f<numFaces; f++) { const PetscScalar *ncx; const CellGeom *ncg; const PetscInt *fcells; PetscInt face = faces[f],ncell; PetscScalar v[DIM]; PetscBool ghost; ierr = IsExteriorGhostFace(dm,face,&ghost);CHKERRQ(ierr); if (ghost) continue; ierr = DMPlexGetSupport(dm,face,&fcells);CHKERRQ(ierr); ncell = cell == fcells[0] ? fcells[1] : fcells[0]; /*The expression (x ? y : z) has the value of y if x is nonzero, z otherwise */ ierr = DMPlexPointLocalRead(dm,ncell,x,&ncx);CHKERRQ(ierr); ierr = DMPlexPointLocalRead(dmCell,ncell,cellgeom,&ncg);CHKERRQ(ierr); Waxpy2(-1, cg->centroid, ncg->centroid, v); for (i=0; i<dof; i++) { /* We use the symmetric slope limited form of Berger, Aftosmis, and Murman 2005 */ PetscScalar phi,flim = 0.5 * (ncx[i] - cx[i]) / Dot2(&cgrad[i*DIM],v); phi = (*user->LimitGrad)(flim); cellPhi[i] = PetscMin(cellPhi[i],phi); } } /* Apply limiter to gradient */ for (i=0; i<dof; i++) Scale2(cellPhi[i],&cgrad[i*DIM],&cgrad[i*DIM]); ierr = PetscFree(cellPhi);CHKERRQ(ierr); ierr = VecRestoreArray(Grad,&grad);CHKERRQ(ierr); } ierr = DMGetLocalVector(dmGrad,&locGradLimiter);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dmGrad,Grad,INSERT_VALUES,locGradLimiter);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dmGrad,Grad,INSERT_VALUES,locGradLimiter);CHKERRQ(ierr); ierr = VecCopy(TempVec, Grad);CHKERRQ(ierr);/*Restore the vector*/ ierr = DMGetLocalVector(dmGrad,&locGrad);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dmGrad,Grad,INSERT_VALUES,locGrad);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dmGrad,Grad,INSERT_VALUES,locGrad);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dmGrad,&Grad);CHKERRQ(ierr); ierr = VecDestroy(&TempVec);CHKERRQ(ierr); { const PetscScalar *grad, *gradlimiter; ierr = VecGetArrayRead(locGrad,&grad);CHKERRQ(ierr); ierr = VecGetArrayRead(locGradLimiter,&gradlimiter);CHKERRQ(ierr); for (face=fStart; face<fEnd; face++) { const PetscInt *cells; PetscInt ghost,i,j; PetscScalar *fluxcon, *fluxdiff, *fx[2]; const FaceGeom *fg; const CellGeom *cg[2]; const PetscScalar *cx[2],*cgrad[2], *cgradlimiter[2]; PetscScalar *uL, *uR; PetscReal FaceArea; ierr = PetscMalloc(phys->dof * phys->dof * sizeof(PetscScalar), &fluxcon);CHKERRQ(ierr); /*For the convection terms*/ ierr = PetscMalloc(phys->dof * phys->dof * sizeof(PetscScalar), &fluxdiff);CHKERRQ(ierr); /*For the diffusion terms*/ ierr = PetscMalloc(phys->dof * sizeof(PetscScalar), &uL);CHKERRQ(ierr); ierr = PetscMalloc(phys->dof * sizeof(PetscScalar), &uR);CHKERRQ(ierr); fx[0] = uL; fx[1] = uR; ierr = DMPlexGetLabelValue(dm, "ghost", face, &ghost);CHKERRQ(ierr); if (ghost >= 0) continue; ierr = DMPlexGetSupport(dm, face, &cells);CHKERRQ(ierr); ierr = DMPlexPointLocalRead(dmFace,face,facegeom,&fg);CHKERRQ(ierr); for (i=0; i<2; i++) { PetscScalar dx[DIM]; ierr = DMPlexPointLocalRead(dmCell,cells[i],cellgeom,&cg[i]);CHKERRQ(ierr); ierr = DMPlexPointLocalRead(dm,cells[i],x,&cx[i]);CHKERRQ(ierr); ierr = DMPlexPointLocalRead(dmGrad,cells[i],gradlimiter,&cgradlimiter[i]);CHKERRQ(ierr); ierr = DMPlexPointLocalRead(dmGrad,cells[i],grad,&cgrad[i]);CHKERRQ(ierr); Waxpy2(-1,cg[i]->centroid,fg->centroid,dx); for (j=0; j<dof; j++) { fx[i][j] = cx[i][j] + Dot2(cgradlimiter[i],dx); } /*fx[0] and fx[1] are the value of the variables on the left and right side of the face, respectively, that is u_L and u_R.*/ } ierr = RiemannSolver_Rusanov_Jacobian(user, cgrad[0], cgrad[1], fg->centroid, cg[0]->centroid, cg[1]->centroid, fg->normal, fx[0], fx[1], fluxcon, fluxdiff);CHKERRQ(ierr); ierr = DMPlexComputeCellGeometryFVM(dm, face, &FaceArea, NULL, NULL);CHKERRQ(ierr); /*Compute the face area*/ for (i=0; i<phys->dof; i++) { for (j=0; j<phys->dof; j++) { if(cells[0]<user->cEndInterior) CellValues[cells[0]*dof*dof + i*dof + j] -= cells[0]*1.0; if(cells[1]<user->cEndInterior) CellValues[cells[1]*dof*dof + i*dof + j] += cells[1]*1.2; } } // ierr = PetscPrintf(PETSC_COMM_WORLD,"\n");CHKERRQ(ierr); ierr = PetscFree(fluxcon);CHKERRQ(ierr); ierr = PetscFree(fluxdiff);CHKERRQ(ierr); ierr = PetscFree(uL);CHKERRQ(ierr); ierr = PetscFree(uR);CHKERRQ(ierr); } ierr = VecRestoreArrayRead(locGrad,&grad);CHKERRQ(ierr); ierr = VecRestoreArrayRead(locGradLimiter,&gradlimiter);CHKERRQ(ierr); } ierr = VecRestoreArrayRead(user->facegeom,&facegeom);CHKERRQ(ierr); ierr = VecRestoreArrayRead(user->cellgeom,&cellgeom);CHKERRQ(ierr); ierr = VecRestoreArrayRead(locX,&x);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dmGrad,&locGradLimiter);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dmGrad,&locGrad);CHKERRQ(ierr); PetscFunctionReturn(0); }