PETSC_STATIC_INLINE PetscErrorCode DMInterpolate_Tetrahedron_Private(DMInterpolationInfo ctx, DM dm, Vec xLocal, Vec v) { PetscReal *v0, *J, *invJ, detJ; PetscScalar *a, *coords; PetscInt p; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscMalloc3(ctx->dim,&v0,ctx->dim*ctx->dim,&J,ctx->dim*ctx->dim,&invJ);CHKERRQ(ierr); ierr = VecGetArray(ctx->coords, &coords);CHKERRQ(ierr); ierr = VecGetArray(v, &a);CHKERRQ(ierr); for (p = 0; p < ctx->n; ++p) { PetscInt c = ctx->cells[p]; const PetscInt order[3] = {2, 1, 3}; PetscScalar *x = NULL; PetscReal xi[4]; PetscInt d, f, comp; ierr = DMPlexComputeCellGeometry(dm, c, v0, J, invJ, &detJ);CHKERRQ(ierr); if (detJ <= 0.0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid determinant %g for element %d", detJ, c); ierr = DMPlexVecGetClosure(dm, NULL, xLocal, c, NULL, &x);CHKERRQ(ierr); for (comp = 0; comp < ctx->dof; ++comp) a[p*ctx->dof+comp] = x[0*ctx->dof+comp]; for (d = 0; d < ctx->dim; ++d) { xi[d] = 0.0; for (f = 0; f < ctx->dim; ++f) xi[d] += invJ[d*ctx->dim+f]*0.5*PetscRealPart(coords[p*ctx->dim+f] - v0[f]); for (comp = 0; comp < ctx->dof; ++comp) a[p*ctx->dof+comp] += PetscRealPart(x[order[d]*ctx->dof+comp] - x[0*ctx->dof+comp])*xi[d]; } ierr = DMPlexVecRestoreClosure(dm, NULL, xLocal, c, NULL, &x);CHKERRQ(ierr); } ierr = VecRestoreArray(v, &a);CHKERRQ(ierr); ierr = VecRestoreArray(ctx->coords, &coords);CHKERRQ(ierr); ierr = PetscFree3(v0, J, invJ);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode ReadData2D(DM dm, Vec u, AppCtx *user) { PetscInt cStart, cEnd, cell; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); for (cell = cStart; cell < cEnd; ++cell) { PetscScalar *closure = NULL; PetscInt closureSize, ki, kj, f, c, foff = 0, o = 0; ierr = DMPlexVecGetClosure(dm, NULL, u, cell, &closureSize, &closure);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D\n", cell);CHKERRQ(ierr); for (f = 0; f < user->Nf; ++f) { ierr = PetscPrintf(PETSC_COMM_SELF, " Field %D\n", f);CHKERRQ(ierr); for (kj = user->k[f]; kj >= 0; --kj) { for (ki = 0; ki <= user->k[f]; ++ki) { if (ki > 0) {ierr = PetscPrintf(PETSC_COMM_SELF, " ");CHKERRQ(ierr);} for (c = 0; c < user->Nc[f]; ++c) { if (c > 0) ierr = PetscPrintf(PETSC_COMM_SELF, ",");CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "%2.0f", closure[(kj*(user->k[f]+1) + ki)*user->Nc[f]+c + foff]);CHKERRQ(ierr); } } ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); } ierr = PetscPrintf(PETSC_COMM_SELF, "\n\n");CHKERRQ(ierr); foff += PetscSqr(user->k[f]+1); } ierr = DMPlexVecRestoreClosure(dm, NULL, u, cell, &closureSize, &closure);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "\n\n");CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode TestVecClosure(DM dm, AppCtx *user) { PetscSection s; Vec v; PetscInt numRuns, cStart, cEnd, c, i; PetscScalar tmpArray[64]; PetscScalar *userArray = user->reuseArray ? tmpArray : NULL; PetscReal maxTimePerRun = user->maxVecClosureTime; PetscStageLog stageLog; PetscEventPerfLog eventLog; PetscInt stage; PetscLogEvent event; PetscEventPerfInfo eventInfo; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLogStageRegister("DMPlex Vector Closure Test", &stage);CHKERRQ(ierr); ierr = PetscLogEventRegister("VecClosure", PETSC_OBJECT_CLASSID, &event);CHKERRQ(ierr); ierr = PetscLogStagePush(stage);CHKERRQ(ierr); ierr = DMPlexCreateSection(dm, user->dim, user->numFields, user->numComponents, user->numDof, 0, NULL, NULL, &s);CHKERRQ(ierr); ierr = DMSetDefaultSection(dm, s);CHKERRQ(ierr); ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); ierr = DMGetLocalVector(dm, &v);CHKERRQ(ierr); ierr = PetscLogEventBegin(event,0,0,0,0);CHKERRQ(ierr); for (i = 0; i < user->iterations; ++i) { for (c = cStart; c < cEnd; ++c) { PetscScalar *closure = userArray; PetscInt closureSize = 64;; ierr = DMPlexVecGetClosure(dm, s, v, c, &closureSize, &closure);CHKERRQ(ierr); if (!user->reuseArray) {ierr = DMPlexVecRestoreClosure(dm, s, v, c, &closureSize, &closure);CHKERRQ(ierr);} } } ierr = PetscLogEventEnd(event,0,0,0,0);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm, &v);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); ierr = PetscLogGetStageLog(&stageLog); ierr = PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog); numRuns = (cEnd-cStart) * user->iterations; eventInfo = eventLog->eventInfo[event]; if (eventInfo.count != 1) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of event calls %d should be %d", eventInfo.count, 1); if ((PetscInt) eventInfo.flops != 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of event flops %d should be %d", (PetscInt) eventInfo.flops, 0); if (eventInfo.time > maxTimePerRun * numRuns) { ierr = PetscPrintf(PETSC_COMM_SELF, "VecClosures: %d Average time per cone: %gs standard: %gs\n", numRuns, eventInfo.time/numRuns, maxTimePerRun); if (user->errors) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Average time for vector closure %g > standard %g", eventInfo.time/numRuns, maxTimePerRun); } PetscFunctionReturn(0); }
static PetscErrorCode CreatePoints_Centroid(DM dm, PetscInt *Np, PetscReal **pcoords, PetscBool *pointsAllProcs, AppCtx *ctx) { PetscSection coordSection; Vec coordsLocal; PetscInt spaceDim, p; PetscMPIInt rank; PetscErrorCode ierr; PetscFunctionBegin; ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); ierr = DMGetCoordinateDim(dm, &spaceDim);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 0, NULL, Np);CHKERRQ(ierr); ierr = PetscCalloc1(*Np * spaceDim, pcoords);CHKERRQ(ierr); for (p = 0; p < *Np; ++p) { PetscScalar *coords = NULL; PetscInt size, num, n, d; ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, p, &size, &coords);CHKERRQ(ierr); num = size/spaceDim; for (n = 0; n < num; ++n) { for (d = 0; d < spaceDim; ++d) (*pcoords)[p*spaceDim+d] += PetscRealPart(coords[n*spaceDim+d]) / num; } ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%d]Point %D (", rank, p);CHKERRQ(ierr); for (d = 0; d < spaceDim; ++d) { ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%g", (double)(*pcoords)[p*spaceDim+d]);CHKERRQ(ierr); if (d < spaceDim-1) {ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD, ", ");CHKERRQ(ierr);} } ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD, ")\n");CHKERRQ(ierr); ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, p, &num, &coords);CHKERRQ(ierr); } ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD, NULL);CHKERRQ(ierr); *pointsAllProcs = PETSC_FALSE; PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat Amat; PetscErrorCode ierr; SNES snes; KSP ksp; MPI_Comm comm; PetscMPIInt npe,rank; PetscLogStage stage[7]; PetscBool test_nonzero_cols=PETSC_FALSE,use_nearnullspace=PETSC_TRUE; Vec xx,bb; PetscInt iter,i,N,dim=3,cells[3]={1,1,1},max_conv_its,local_sizes[7],run_type=1; DM dm,distdm,basedm; PetscBool flg; char convType[256]; PetscReal Lx,mdisp[10],err[10]; const char * const options[10] = {"-ex56_dm_refine 0", "-ex56_dm_refine 1", "-ex56_dm_refine 2", "-ex56_dm_refine 3", "-ex56_dm_refine 4", "-ex56_dm_refine 5", "-ex56_dm_refine 6", "-ex56_dm_refine 7", "-ex56_dm_refine 8", "-ex56_dm_refine 9"}; PetscFunctionBeginUser; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; comm = PETSC_COMM_WORLD; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = MPI_Comm_size(comm, &npe);CHKERRQ(ierr); /* options */ ierr = PetscOptionsBegin(comm,NULL,"3D bilinear Q1 elasticity options","");CHKERRQ(ierr); { i = 3; ierr = PetscOptionsIntArray("-cells", "Number of (flux tube) processor in each dimension", "ex56.c", cells, &i, NULL);CHKERRQ(ierr); Lx = 1.; /* or ne for rod */ max_conv_its = 3; ierr = PetscOptionsInt("-max_conv_its","Number of iterations in convergence study","",max_conv_its,&max_conv_its,NULL);CHKERRQ(ierr); if (max_conv_its<=0 || max_conv_its>7) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_USER, "Bad number of iterations for convergence test (%D)",max_conv_its); ierr = PetscOptionsReal("-lx","Length of domain","",Lx,&Lx,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alpha","material coefficient inside circle","",s_soft_alpha,&s_soft_alpha,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-test_nonzero_cols","nonzero test","",test_nonzero_cols,&test_nonzero_cols,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-use_mat_nearnullspace","MatNearNullSpace API test","",use_nearnullspace,&use_nearnullspace,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-run_type","0: twisting load on cantalever, 1: 3rd order accurate convergence test","",run_type,&run_type,NULL);CHKERRQ(ierr); i = 3; ierr = PetscOptionsInt("-mat_block_size","","",i,&i,&flg);CHKERRQ(ierr); if (!flg || i!=3) SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_USER, "'-mat_block_size 3' must be set (%D) and = 3 (%D)",flg,flg? i : 3); } ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscLogStageRegister("Mesh Setup", &stage[6]);CHKERRQ(ierr); ierr = PetscLogStageRegister("1st Setup", &stage[0]);CHKERRQ(ierr); ierr = PetscLogStageRegister("1st Solve", &stage[1]);CHKERRQ(ierr); /* create DM, Plex calls DMSetup */ ierr = PetscLogStagePush(stage[6]);CHKERRQ(ierr); ierr = DMPlexCreateHexBoxMesh(comm, dim, cells, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, &dm);CHKERRQ(ierr); { DMLabel label; IS is; ierr = DMCreateLabel(dm, "boundary");CHKERRQ(ierr); ierr = DMGetLabel(dm, "boundary", &label);CHKERRQ(ierr); ierr = DMPlexMarkBoundaryFaces(dm, label);CHKERRQ(ierr); if (run_type==0) { ierr = DMGetStratumIS(dm, "boundary", 1, &is);CHKERRQ(ierr); ierr = DMCreateLabel(dm,"Faces");CHKERRQ(ierr); if (is) { PetscInt d, f, Nf; const PetscInt *faces; PetscInt csize; PetscSection cs; Vec coordinates ; DM cdm; ierr = ISGetLocalSize(is, &Nf);CHKERRQ(ierr); ierr = ISGetIndices(is, &faces);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); ierr = DMGetDefaultSection(cdm, &cs);CHKERRQ(ierr); /* Check for each boundary face if any component of its centroid is either 0.0 or 1.0 */ for (f = 0; f < Nf; ++f) { PetscReal faceCoord; PetscInt b,v; PetscScalar *coords = NULL; PetscInt Nv; ierr = DMPlexVecGetClosure(cdm, cs, coordinates, faces[f], &csize, &coords);CHKERRQ(ierr); Nv = csize/dim; /* Calculate mean coordinate vector */ for (d = 0; d < dim; ++d) { faceCoord = 0.0; for (v = 0; v < Nv; ++v) faceCoord += PetscRealPart(coords[v*dim+d]); faceCoord /= Nv; for (b = 0; b < 2; ++b) { if (PetscAbs(faceCoord - b) < PETSC_SMALL) { /* domain have not been set yet, still [0,1]^3 */ ierr = DMSetLabelValue(dm, "Faces", faces[f], d*2+b+1);CHKERRQ(ierr); } } } ierr = DMPlexVecRestoreClosure(cdm, cs, coordinates, faces[f], &csize, &coords);CHKERRQ(ierr); } ierr = ISRestoreIndices(is, &faces);CHKERRQ(ierr); } ierr = ISDestroy(&is);CHKERRQ(ierr); ierr = DMGetLabel(dm, "Faces", &label);CHKERRQ(ierr); ierr = DMPlexLabelComplete(dm, label);CHKERRQ(ierr); } } { PetscInt dimEmbed, i; PetscInt nCoords; PetscScalar *coords,bounds[] = {0,Lx,-.5,.5,-.5,.5,}; /* x_min,x_max,y_min,y_max */ Vec coordinates; if (run_type==1) { for (i = 0; i < 2*dim; i++) bounds[i] = (i%2) ? 1 : 0; } ierr = DMGetCoordinatesLocal(dm,&coordinates);CHKERRQ(ierr); ierr = DMGetCoordinateDim(dm,&dimEmbed);CHKERRQ(ierr); if (dimEmbed != dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"dimEmbed != dim %D",dimEmbed);CHKERRQ(ierr); ierr = VecGetLocalSize(coordinates,&nCoords);CHKERRQ(ierr); if (nCoords % dimEmbed) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Coordinate vector the wrong size");CHKERRQ(ierr); ierr = VecGetArray(coordinates,&coords);CHKERRQ(ierr); for (i = 0; i < nCoords; i += dimEmbed) { PetscInt j; PetscScalar *coord = &coords[i]; for (j = 0; j < dimEmbed; j++) { coord[j] = bounds[2 * j] + coord[j] * (bounds[2 * j + 1] - bounds[2 * j]); } } ierr = VecRestoreArray(coordinates,&coords);CHKERRQ(ierr); ierr = DMSetCoordinatesLocal(dm,coordinates);CHKERRQ(ierr); } /* convert to p4est, and distribute */ ierr = PetscOptionsBegin(comm, "", "Mesh conversion options", "DMPLEX");CHKERRQ(ierr); ierr = PetscOptionsFList("-dm_type","Convert DMPlex to another format (should not be Plex!)","ex56.c",DMList,DMPLEX,convType,256,&flg);CHKERRQ(ierr); ierr = PetscOptionsEnd(); if (flg) { DM newdm; ierr = DMConvert(dm,convType,&newdm);CHKERRQ(ierr); if (newdm) { const char *prefix; PetscBool isForest; ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,&prefix);CHKERRQ(ierr); ierr = PetscObjectSetOptionsPrefix((PetscObject)newdm,prefix);CHKERRQ(ierr); ierr = DMIsForest(newdm,&isForest);CHKERRQ(ierr); if (isForest) { } else SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER, "Converted to non Forest?"); ierr = DMDestroy(&dm);CHKERRQ(ierr); dm = newdm; } else SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER, "Convert failed?"); } else { /* Plex Distribute mesh over processes */ ierr = DMPlexDistribute(dm, 0, NULL, &distdm);CHKERRQ(ierr); if (distdm) { const char *prefix; ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,&prefix);CHKERRQ(ierr); ierr = PetscObjectSetOptionsPrefix((PetscObject)distdm,prefix);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); dm = distdm; } } ierr = PetscLogStagePop();CHKERRQ(ierr); basedm = dm; dm = NULL; for (iter=0 ; iter<max_conv_its ; iter++) { ierr = PetscLogStagePush(stage[6]);CHKERRQ(ierr); /* make new DM */ ierr = DMClone(basedm, &dm);CHKERRQ(ierr); ierr = PetscObjectSetOptionsPrefix((PetscObject) dm, "ex56_");CHKERRQ(ierr); ierr = PetscObjectSetName( (PetscObject)dm,"Mesh");CHKERRQ(ierr); ierr = PetscOptionsClearValue(NULL,"-ex56_dm_refine");CHKERRQ(ierr); ierr = PetscOptionsInsertString(NULL,options[iter]);CHKERRQ(ierr); ierr = DMSetFromOptions(dm);CHKERRQ(ierr); /* refinement done here in Plex, p4est */ /* snes */ ierr = SNESCreate(comm, &snes);CHKERRQ(ierr); ierr = SNESSetDM(snes, dm);CHKERRQ(ierr); /* fem */ { const PetscInt Ncomp = dim; const PetscInt components[] = {0,1,2}; const PetscInt Nfid = 1, Npid = 1; const PetscInt fid[] = {1}; /* The fixed faces (x=0) */ const PetscInt pid[] = {2}; /* The faces with loading (x=L_x) */ PetscFE fe; PetscDS prob; DM cdm = dm; ierr = PetscFECreateDefault(dm, dim, dim, PETSC_FALSE, NULL, PETSC_DECIDE, &fe);CHKERRQ(ierr); /* elasticity */ ierr = PetscObjectSetName((PetscObject) fe, "deformation");CHKERRQ(ierr); /* FEM prob */ ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); ierr = PetscDSSetDiscretization(prob, 0, (PetscObject) fe);CHKERRQ(ierr); /* setup problem */ if (run_type==1) { ierr = PetscDSSetJacobian(prob, 0, 0, NULL, NULL, NULL, g3_uu_3d);CHKERRQ(ierr); ierr = PetscDSSetResidual(prob, 0, f0_u_x4, f1_u_3d);CHKERRQ(ierr); } else { ierr = PetscDSSetJacobian(prob, 0, 0, NULL, NULL, NULL, g3_uu_3d_alpha);CHKERRQ(ierr); ierr = PetscDSSetResidual(prob, 0, f0_u, f1_u_3d_alpha);CHKERRQ(ierr); ierr = PetscDSSetBdResidual(prob, 0, f0_bd_u_3d, f1_bd_u);CHKERRQ(ierr); } /* bcs */ if (run_type==1) { PetscInt id = 1; ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall", "boundary", 0, 0, NULL, (void (*)()) zero, 1, &id, NULL);CHKERRQ(ierr); } else { ierr = PetscDSAddBoundary(prob, DM_BC_ESSENTIAL, "fixed", "Faces", 0, Ncomp, components, (void (*)()) zero, Nfid, fid, NULL);CHKERRQ(ierr); ierr = PetscDSAddBoundary(prob, DM_BC_NATURAL, "traction", "Faces", 0, Ncomp, components, NULL, Npid, pid, NULL);CHKERRQ(ierr); } while (cdm) { ierr = DMSetDS(cdm,prob);CHKERRQ(ierr); ierr = DMGetCoarseDM(cdm, &cdm);CHKERRQ(ierr); } ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); } /* vecs & mat */ ierr = DMCreateGlobalVector(dm,&xx);CHKERRQ(ierr); ierr = VecDuplicate(xx, &bb);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) bb, "b");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) xx, "u");CHKERRQ(ierr); ierr = DMCreateMatrix(dm, &Amat);CHKERRQ(ierr); ierr = VecGetSize(bb,&N);CHKERRQ(ierr); local_sizes[iter] = N; ierr = PetscPrintf(PETSC_COMM_WORLD,"[%d]%s %d global equations, %d vertices\n",rank,PETSC_FUNCTION_NAME,N,N/dim);CHKERRQ(ierr); if (use_nearnullspace && N/dim > 1) { /* Set up the near null space (a.k.a. rigid body modes) that will be used by the multigrid preconditioner */ DM subdm; MatNullSpace nearNullSpace; PetscInt fields = 0; PetscObject deformation; ierr = DMCreateSubDM(dm, 1, &fields, NULL, &subdm);CHKERRQ(ierr); ierr = DMPlexCreateRigidBody(subdm, &nearNullSpace);CHKERRQ(ierr); ierr = DMGetField(dm, 0, &deformation);CHKERRQ(ierr); ierr = PetscObjectCompose(deformation, "nearnullspace", (PetscObject) nearNullSpace);CHKERRQ(ierr); ierr = DMDestroy(&subdm);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&nearNullSpace);CHKERRQ(ierr); /* created by DM and destroyed by Mat */ } ierr = DMPlexSetSNESLocalFEM(dm,NULL,NULL,NULL);CHKERRQ(ierr); ierr = SNESSetJacobian(snes, Amat, Amat, NULL, NULL);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = DMSetUp(dm);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); ierr = PetscLogStagePush(stage[0]);CHKERRQ(ierr); /* ksp */ ierr = SNESGetKSP(snes, &ksp);CHKERRQ(ierr); ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); /* test BCs */ ierr = VecZeroEntries(xx);CHKERRQ(ierr); if (test_nonzero_cols) { if (rank==0) ierr = VecSetValue(xx,0,1.0,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(xx);CHKERRQ(ierr); ierr = VecAssemblyEnd(xx);CHKERRQ(ierr); } ierr = VecZeroEntries(bb);CHKERRQ(ierr); ierr = VecGetSize(bb,&i);CHKERRQ(ierr); local_sizes[iter] = i; ierr = PetscPrintf(PETSC_COMM_WORLD,"[%d]%s %d equations in vector, %d vertices\n",rank,PETSC_FUNCTION_NAME,i,i/dim);CHKERRQ(ierr); /* setup solver, dummy solve to really setup */ if (0) { ierr = KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); ierr = SNESSolve(snes, bb, xx);CHKERRQ(ierr); ierr = KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,50);CHKERRQ(ierr); ierr = VecZeroEntries(xx);CHKERRQ(ierr); } ierr = PetscLogStagePop();CHKERRQ(ierr); /* solve */ ierr = PetscLogStagePush(stage[1]);CHKERRQ(ierr); ierr = SNESSolve(snes, bb, xx);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); ierr = VecNorm(xx,NORM_INFINITY,&mdisp[iter]);CHKERRQ(ierr); ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr); { PetscViewer viewer = NULL; PetscViewerFormat fmt; ierr = PetscOptionsGetViewer(comm,"ex56_","-vec_view",&viewer,&fmt,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerPushFormat(viewer,fmt);CHKERRQ(ierr); ierr = VecView(xx,viewer);CHKERRQ(ierr); ierr = VecView(bb,viewer);CHKERRQ(ierr); ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); } ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } /* Free work space */ ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = VecDestroy(&xx);CHKERRQ(ierr); ierr = VecDestroy(&bb);CHKERRQ(ierr); ierr = MatDestroy(&Amat);CHKERRQ(ierr); } ierr = DMDestroy(&basedm);CHKERRQ(ierr); if (run_type==1) { err[0] = 59.975208 - mdisp[0]; /* error with what I think is the exact solution */ } else { err[0] = 171.038 - mdisp[0]; } for (iter=1 ; iter<max_conv_its ; iter++) { if (run_type==1) { err[iter] = 59.975208 - mdisp[iter]; } else { err[iter] = 171.038 - mdisp[iter]; } PetscPrintf(PETSC_COMM_WORLD,"[%d]%s %D) N=%12D, max displ=%9.7e, disp diff=%9.2e, error=%4.3e, rate=%3.2g\n", rank,PETSC_FUNCTION_NAME,iter,local_sizes[iter],mdisp[iter], mdisp[iter]-mdisp[iter-1],err[iter],log(err[iter-1]/err[iter])/log(2.)); } ierr = PetscFinalize(); return ierr; }
static PetscErrorCode TestVecClosure(DM dm, PetscBool useIndex, PetscBool useSpectral, AppCtx *user) { PetscSection s; Vec v; PetscInt numRuns, cStart, cEnd, c, i; PetscScalar tmpArray[64]; PetscScalar *userArray = user->reuseArray ? tmpArray : NULL; PetscReal maxTimePerRun = user->maxVecClosureTime; PetscLogStage stage; PetscLogEvent event; PetscEventPerfInfo eventInfo; PetscErrorCode ierr; PetscFunctionBegin; if (useIndex) { if (useSpectral) { ierr = PetscLogStageRegister("DMPlex Vector Closure with Index Test", &stage);CHKERRQ(ierr); ierr = PetscLogEventRegister("VecClosureInd", PETSC_OBJECT_CLASSID, &event);CHKERRQ(ierr); } else { ierr = PetscLogStageRegister("DMPlex Vector Spectral Closure with Index Test", &stage);CHKERRQ(ierr); ierr = PetscLogEventRegister("VecClosureSpecInd", PETSC_OBJECT_CLASSID, &event);CHKERRQ(ierr); } } else { if (useSpectral) { ierr = PetscLogStageRegister("DMPlex Vector Spectral Closure Test", &stage);CHKERRQ(ierr); ierr = PetscLogEventRegister("VecClosureSpec", PETSC_OBJECT_CLASSID, &event);CHKERRQ(ierr); } else { ierr = PetscLogStageRegister("DMPlex Vector Closure Test", &stage);CHKERRQ(ierr); ierr = PetscLogEventRegister("VecClosure", PETSC_OBJECT_CLASSID, &event);CHKERRQ(ierr); } } ierr = PetscLogStagePush(stage);CHKERRQ(ierr); ierr = DMPlexCreateSection(dm, user->dim, user->numFields, user->numComponents, user->numDof, 0, NULL, NULL, NULL, NULL, &s);CHKERRQ(ierr); ierr = DMSetDefaultSection(dm, s);CHKERRQ(ierr); if (useIndex) {ierr = DMPlexCreateClosureIndex(dm, s);CHKERRQ(ierr);} if (useSpectral) {ierr = DMPlexCreateSpectralClosurePermutation(dm, s);CHKERRQ(ierr);} ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); ierr = DMGetLocalVector(dm, &v);CHKERRQ(ierr); ierr = PetscLogEventBegin(event,0,0,0,0);CHKERRQ(ierr); for (i = 0; i < user->iterations; ++i) { for (c = cStart; c < cEnd; ++c) { PetscScalar *closure = userArray; PetscInt closureSize = 64; ierr = DMPlexVecGetClosure(dm, s, v, c, &closureSize, &closure);CHKERRQ(ierr); if (!user->reuseArray) {ierr = DMPlexVecRestoreClosure(dm, s, v, c, &closureSize, &closure);CHKERRQ(ierr);} } } ierr = PetscLogEventEnd(event,0,0,0,0);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm, &v);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); ierr = PetscLogEventGetPerfInfo(stage, event, &eventInfo);CHKERRQ(ierr); numRuns = (cEnd-cStart) * user->iterations; if (eventInfo.count != 1) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of event calls %d should be %d", eventInfo.count, 1); if ((PetscInt) eventInfo.flops != 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of event flops %d should be %d", (PetscInt) eventInfo.flops, 0); if (eventInfo.time > maxTimePerRun * numRuns) { const char *title = "VecClosures"; const char *titleIndex = "VecClosures with Index"; const char *titleSpec = "VecClosures Spectral"; const char *titleSpecIndex = "VecClosures Spectral with Index"; ierr = PetscPrintf(PETSC_COMM_SELF, "%s: %d Average time per vector closure: %gs standard: %gs\n", useIndex ? (useSpectral ? titleSpecIndex : titleIndex) : (useSpectral ? titleSpec : title), numRuns, eventInfo.time/numRuns, maxTimePerRun); if (user->errors) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Average time for vector closure %g > standard %g", eventInfo.time/numRuns, maxTimePerRun); } PetscFunctionReturn(0); }
PetscErrorCode DMCoarsen_Plex(DM dm, MPI_Comm comm, DM *dmCoarsened) { DM_Plex *mesh = (DM_Plex*) dm->data; #ifdef PETSC_HAVE_PRAGMATIC DM udm, coordDM; DMLabel bd; Mat A; Vec coordinates, mb, mx; PetscSection coordSection; const PetscScalar *coords; double *coarseCoords; IS bdIS; PetscReal *x, *y, *z, *eqns, *metric; PetscReal coarseRatio = PetscSqr(0.5); const PetscInt *faces; PetscInt *cells, *bdFaces, *bdFaceIds; PetscInt dim, numCorners, cStart, cEnd, numCells, numCoarseCells, c, vStart, vEnd, numVertices, numCoarseVertices, v, numBdFaces, f, maxConeSize, size, bdSize, coff; #endif PetscErrorCode ierr; PetscFunctionBegin; #ifdef PETSC_HAVE_PRAGMATIC if (!mesh->coarseMesh) { ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); ierr = DMGetCoordinateDM(dm, &coordDM);CHKERRQ(ierr); ierr = DMGetDefaultSection(coordDM, &coordSection);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); ierr = DMPlexUninterpolate(dm, &udm);CHKERRQ(ierr); ierr = DMPlexGetMaxSizes(udm, &maxConeSize, NULL);CHKERRQ(ierr); numCells = cEnd - cStart; numVertices = vEnd - vStart; ierr = PetscCalloc5(numVertices, &x, numVertices, &y, numVertices, &z, numVertices*PetscSqr(dim), &metric, numCells*maxConeSize, &cells);CHKERRQ(ierr); ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); for (v = vStart; v < vEnd; ++v) { PetscInt off; ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); x[v-vStart] = coords[off+0]; y[v-vStart] = coords[off+1]; if (dim > 2) z[v-vStart] = coords[off+2]; } ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); for (c = 0, coff = 0; c < numCells; ++c) { const PetscInt *cone; PetscInt coneSize, cl; ierr = DMPlexGetConeSize(udm, c, &coneSize);CHKERRQ(ierr); ierr = DMPlexGetCone(udm, c, &cone);CHKERRQ(ierr); for (cl = 0; cl < coneSize; ++cl) cells[coff++] = cone[cl] - vStart; } switch (dim) { case 2: pragmatic_2d_init(&numVertices, &numCells, cells, x, y); break; case 3: pragmatic_3d_init(&numVertices, &numCells, cells, x, y, z); break; default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No Pragmatic coarsening defined for dimension %d", dim); } /* Create boundary mesh */ ierr = DMLabelCreate("boundary", &bd);CHKERRQ(ierr); ierr = DMPlexMarkBoundaryFaces(dm, bd);CHKERRQ(ierr); ierr = DMLabelGetStratumIS(bd, 1, &bdIS);CHKERRQ(ierr); ierr = DMLabelGetStratumSize(bd, 1, &numBdFaces);CHKERRQ(ierr); ierr = ISGetIndices(bdIS, &faces);CHKERRQ(ierr); for (f = 0, bdSize = 0; f < numBdFaces; ++f) { PetscInt *closure = NULL; PetscInt closureSize, cl; ierr = DMPlexGetTransitiveClosure(dm, faces[f], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); for (cl = 0; cl < closureSize*2; cl += 2) { if ((closure[cl] >= vStart) && (closure[cl] < vEnd)) ++bdSize; } ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); } ierr = PetscMalloc2(bdSize, &bdFaces, numBdFaces, &bdFaceIds);CHKERRQ(ierr); for (f = 0, bdSize = 0; f < numBdFaces; ++f) { PetscInt *closure = NULL; PetscInt closureSize, cl; ierr = DMPlexGetTransitiveClosure(dm, faces[f], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); for (cl = 0; cl < closureSize*2; cl += 2) { if ((closure[cl] >= vStart) && (closure[cl] < vEnd)) bdFaces[bdSize++] = closure[cl] - vStart; } /* TODO Fix */ bdFaceIds[f] = 1; ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); } ierr = ISDestroy(&bdIS);CHKERRQ(ierr); ierr = DMLabelDestroy(&bd);CHKERRQ(ierr); pragmatic_set_boundary(&numBdFaces, bdFaces, bdFaceIds); /* Create metric */ size = (dim*(dim+1))/2; ierr = PetscMalloc1(PetscSqr(size), &eqns);CHKERRQ(ierr); ierr = MatCreateSeqDense(PETSC_COMM_SELF, size, size, eqns, &A);CHKERRQ(ierr); ierr = MatCreateVecs(A, &mx, &mb);CHKERRQ(ierr); ierr = VecSet(mb, 1.0);CHKERRQ(ierr); for (c = 0; c < numCells; ++c) { const PetscScalar *sol; PetscScalar *cellCoords = NULL; PetscReal e[3], vol; const PetscInt *cone; PetscInt coneSize, cl, i, j, d, r; ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, NULL, &cellCoords);CHKERRQ(ierr); /* Only works for simplices */ for (i = 0, r = 0; i < dim+1; ++i) { for (j = 0; j < i; ++j, ++r) { for (d = 0; d < dim; ++d) e[d] = cellCoords[i*dim+d] - cellCoords[j*dim+d]; /* FORTRAN ORDERING */ if (dim == 2) { eqns[0*size+r] = PetscSqr(e[0]); eqns[1*size+r] = 2.0*e[0]*e[1]; eqns[2*size+r] = PetscSqr(e[1]); } else { eqns[0*size+r] = PetscSqr(e[0]); eqns[1*size+r] = 2.0*e[0]*e[1]; eqns[2*size+r] = 2.0*e[0]*e[2]; eqns[3*size+r] = PetscSqr(e[1]); eqns[4*size+r] = 2.0*e[1]*e[2]; eqns[5*size+r] = PetscSqr(e[2]); } } } ierr = MatSetUnfactored(A);CHKERRQ(ierr); ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, NULL, &cellCoords);CHKERRQ(ierr); ierr = MatLUFactor(A, NULL, NULL, NULL);CHKERRQ(ierr); ierr = MatSolve(A, mb, mx);CHKERRQ(ierr); ierr = VecGetArrayRead(mx, &sol);CHKERRQ(ierr); ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, NULL, NULL);CHKERRQ(ierr); ierr = DMPlexGetCone(udm, c, &cone);CHKERRQ(ierr); ierr = DMPlexGetConeSize(udm, c, &coneSize);CHKERRQ(ierr); for (cl = 0; cl < coneSize; ++cl) { const PetscInt v = cone[cl] - vStart; if (dim == 2) { metric[v*4+0] += vol*coarseRatio*sol[0]; metric[v*4+1] += vol*coarseRatio*sol[1]; metric[v*4+2] += vol*coarseRatio*sol[1]; metric[v*4+3] += vol*coarseRatio*sol[2]; } else { metric[v*9+0] += vol*coarseRatio*sol[0]; metric[v*9+1] += vol*coarseRatio*sol[1]; metric[v*9+3] += vol*coarseRatio*sol[1]; metric[v*9+2] += vol*coarseRatio*sol[2]; metric[v*9+6] += vol*coarseRatio*sol[2]; metric[v*9+4] += vol*coarseRatio*sol[3]; metric[v*9+5] += vol*coarseRatio*sol[4]; metric[v*9+7] += vol*coarseRatio*sol[4]; metric[v*9+8] += vol*coarseRatio*sol[5]; } } ierr = VecRestoreArrayRead(mx, &sol);CHKERRQ(ierr); } for (v = 0; v < numVertices; ++v) { const PetscInt *support; PetscInt supportSize, s; PetscReal vol, totVol = 0.0; ierr = DMPlexGetSupport(udm, v+vStart, &support);CHKERRQ(ierr); ierr = DMPlexGetSupportSize(udm, v+vStart, &supportSize);CHKERRQ(ierr); for (s = 0; s < supportSize; ++s) {ierr = DMPlexComputeCellGeometryFVM(dm, support[s], &vol, NULL, NULL);CHKERRQ(ierr); totVol += vol;} for (s = 0; s < PetscSqr(dim); ++s) metric[v*PetscSqr(dim)+s] /= totVol; } ierr = VecDestroy(&mx);CHKERRQ(ierr); ierr = VecDestroy(&mb);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = DMDestroy(&udm);CHKERRQ(ierr); ierr = PetscFree(eqns);CHKERRQ(ierr); pragmatic_set_metric(metric); pragmatic_adapt(); /* Read out mesh */ pragmatic_get_info(&numCoarseVertices, &numCoarseCells); ierr = PetscMalloc1(numCoarseVertices*dim, &coarseCoords);CHKERRQ(ierr); switch (dim) { case 2: pragmatic_get_coords_2d(x, y); numCorners = 3; for (v = 0; v < numCoarseVertices; ++v) {coarseCoords[v*2+0] = x[v]; coarseCoords[v*2+1] = y[v];} break; case 3: pragmatic_get_coords_3d(x, y, z); numCorners = 4; for (v = 0; v < numCoarseVertices; ++v) {coarseCoords[v*3+0] = x[v]; coarseCoords[v*3+1] = y[v]; coarseCoords[v*3+2] = z[v];} break; default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No Pragmatic coarsening defined for dimension %d", dim); } pragmatic_get_elements(cells); /* TODO Read out markers for boundary */ ierr = DMPlexCreateFromCellList(PetscObjectComm((PetscObject) dm), dim, numCoarseCells, numCoarseVertices, numCorners, PETSC_TRUE, cells, dim, coarseCoords, &mesh->coarseMesh);CHKERRQ(ierr); pragmatic_finalize(); ierr = PetscFree5(x, y, z, metric, cells);CHKERRQ(ierr); ierr = PetscFree2(bdFaces, bdFaceIds);CHKERRQ(ierr); ierr = PetscFree(coarseCoords);CHKERRQ(ierr); } #endif ierr = PetscObjectReference((PetscObject) mesh->coarseMesh);CHKERRQ(ierr); *dmCoarsened = mesh->coarseMesh; PetscFunctionReturn(0); }
PETSC_STATIC_INLINE PetscErrorCode DMInterpolate_Hex_Private(DMInterpolationInfo ctx, DM dm, Vec xLocal, Vec v) { DM dmCoord; SNES snes; KSP ksp; PC pc; Vec coordsLocal, r, ref, real; Mat J; PetscScalar *a, *coords; PetscInt p; PetscErrorCode ierr; PetscFunctionBegin; ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); ierr = DMGetCoordinateDM(dm, &dmCoord);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_SELF, &snes);CHKERRQ(ierr); ierr = SNESSetOptionsPrefix(snes, "hex_interp_");CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF, &r);CHKERRQ(ierr); ierr = VecSetSizes(r, 3, 3);CHKERRQ(ierr); ierr = VecSetType(r,dm->vectype);CHKERRQ(ierr); ierr = VecDuplicate(r, &ref);CHKERRQ(ierr); ierr = VecDuplicate(r, &real);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_SELF, &J);CHKERRQ(ierr); ierr = MatSetSizes(J, 3, 3, 3, 3);CHKERRQ(ierr); ierr = MatSetType(J, MATSEQDENSE);CHKERRQ(ierr); ierr = MatSetUp(J);CHKERRQ(ierr); ierr = SNESSetFunction(snes, r, HexMap_Private, NULL);CHKERRQ(ierr); ierr = SNESSetJacobian(snes, J, J, HexJacobian_Private, NULL);CHKERRQ(ierr); ierr = SNESGetKSP(snes, &ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); ierr = PCSetType(pc, PCLU);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = VecGetArray(ctx->coords, &coords);CHKERRQ(ierr); ierr = VecGetArray(v, &a);CHKERRQ(ierr); for (p = 0; p < ctx->n; ++p) { PetscScalar *x = NULL, *vertices = NULL; PetscScalar *xi; PetscReal xir[3]; PetscInt c = ctx->cells[p], comp, coordSize, xSize; /* Can make this do all points at once */ ierr = DMPlexVecGetClosure(dmCoord, NULL, coordsLocal, c, &coordSize, &vertices);CHKERRQ(ierr); if (8*3 != coordSize) SETERRQ2(ctx->comm, PETSC_ERR_ARG_SIZ, "Invalid closure size %d should be %d", coordSize, 8*3); ierr = DMPlexVecGetClosure(dm, NULL, xLocal, c, &xSize, &x);CHKERRQ(ierr); if (8*ctx->dof != xSize) SETERRQ2(ctx->comm, PETSC_ERR_ARG_SIZ, "Invalid closure size %d should be %d", xSize, 8*ctx->dof); ierr = SNESSetFunction(snes, NULL, NULL, (void*) vertices);CHKERRQ(ierr); ierr = SNESSetJacobian(snes, NULL, NULL, NULL, (void*) vertices);CHKERRQ(ierr); ierr = VecGetArray(real, &xi);CHKERRQ(ierr); xi[0] = coords[p*ctx->dim+0]; xi[1] = coords[p*ctx->dim+1]; xi[2] = coords[p*ctx->dim+2]; ierr = VecRestoreArray(real, &xi);CHKERRQ(ierr); ierr = SNESSolve(snes, real, ref);CHKERRQ(ierr); ierr = VecGetArray(ref, &xi);CHKERRQ(ierr); xir[0] = PetscRealPart(xi[0]); xir[1] = PetscRealPart(xi[1]); xir[2] = PetscRealPart(xi[2]); for (comp = 0; comp < ctx->dof; ++comp) { a[p*ctx->dof+comp] = x[0*ctx->dof+comp]*(1-xir[0])*(1-xir[1])*(1-xir[2]) + x[3*ctx->dof+comp]* xir[0]*(1-xir[1])*(1-xir[2]) + x[2*ctx->dof+comp]* xir[0]* xir[1]*(1-xir[2]) + x[1*ctx->dof+comp]*(1-xir[0])* xir[1]*(1-xir[2]) + x[4*ctx->dof+comp]*(1-xir[0])*(1-xir[1])* xir[2] + x[5*ctx->dof+comp]* xir[0]*(1-xir[1])* xir[2] + x[6*ctx->dof+comp]* xir[0]* xir[1]* xir[2] + x[7*ctx->dof+comp]*(1-xir[0])* xir[1]* xir[2]; } ierr = VecRestoreArray(ref, &xi);CHKERRQ(ierr); ierr = DMPlexVecRestoreClosure(dmCoord, NULL, coordsLocal, c, &coordSize, &vertices);CHKERRQ(ierr); ierr = DMPlexVecRestoreClosure(dm, NULL, xLocal, c, &xSize, &x);CHKERRQ(ierr); } ierr = VecRestoreArray(v, &a);CHKERRQ(ierr); ierr = VecRestoreArray(ctx->coords, &coords);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = VecDestroy(&ref);CHKERRQ(ierr); ierr = VecDestroy(&real);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); PetscFunctionReturn(0); }