int main(int argc, char **argv) { DM dm; SNES snes; Vec u, r; AppCtx user; PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL, help);CHKERRQ(ierr); ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD, &snes);CHKERRQ(ierr); ierr = CreateMesh(PETSC_COMM_WORLD, &user, &dm);CHKERRQ(ierr); ierr = SNESSetDM(snes, dm);CHKERRQ(ierr); ierr = PetscMalloc(3 * sizeof(void (*)()), &user.exactFuncs);CHKERRQ(ierr); ierr = SetupDiscretization(dm, &user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dm, &u);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, "solution");CHKERRQ(ierr); ierr = VecDuplicate(u, &r);CHKERRQ(ierr); ierr = DMPlexSetSNESLocalFEM(dm,&user,&user,&user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = DMProjectFunction(dm, user.exactFuncs, NULL, INSERT_ALL_VALUES, u);CHKERRQ(ierr); ierr = DMSNESCheckFromOptions(snes, u, user.exactFuncs, NULL);CHKERRQ(ierr); if (user.runType == RUN_FULL) { PetscErrorCode (*initialGuess[3])(PetscInt dim, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx); PetscReal error; initialGuess[0] = zero; initialGuess[1] = zero; initialGuess[2] = zero; ierr = DMProjectFunction(dm, initialGuess, NULL, INSERT_VALUES, u);CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-initial_vec_view");CHKERRQ(ierr); ierr = DMComputeL2Diff(dm, user.exactFuncs, NULL, u, &error);CHKERRQ(ierr); if (error < 1.0e-11) {ierr = PetscPrintf(PETSC_COMM_WORLD, "Initial L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);} else {ierr = PetscPrintf(PETSC_COMM_WORLD, "Initial L_2 Error: %g\n", error);CHKERRQ(ierr);} ierr = SNESSolve(snes, NULL, u);CHKERRQ(ierr); ierr = DMComputeL2Diff(dm, user.exactFuncs, NULL, u, &error);CHKERRQ(ierr); if (error < 1.0e-11) {ierr = PetscPrintf(PETSC_COMM_WORLD, "Final L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);} else {ierr = PetscPrintf(PETSC_COMM_WORLD, "Final L_2 Error: %g\n", error);CHKERRQ(ierr);} } ierr = VecViewFromOptions(u, NULL, "-sol_vec_view");CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = PetscFree(user.exactFuncs);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc, char **argv) { SNES snes; /* nonlinear solver */ DM dm; /* problem definition */ Vec u, r; /* solution and residual */ AppCtx user; /* user-defined work context */ PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr; ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr); ierr = PetscBagCreate(PETSC_COMM_WORLD, sizeof(Parameter), &user.bag);CHKERRQ(ierr); ierr = SetupParameters(&user);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD, &snes);CHKERRQ(ierr); ierr = CreateMesh(PETSC_COMM_WORLD, &user, &dm);CHKERRQ(ierr); ierr = SNESSetDM(snes, dm);CHKERRQ(ierr); ierr = DMSetApplicationContext(dm, &user);CHKERRQ(ierr); /* Setup problem */ ierr = PetscMalloc(2 * sizeof(void (*)(const PetscReal[], PetscScalar *, void *)), &user.exactFuncs);CHKERRQ(ierr); ierr = SetupDiscretization(dm, &user);CHKERRQ(ierr); ierr = DMPlexCreateClosureIndex(dm, NULL);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dm, &u);CHKERRQ(ierr); ierr = VecDuplicate(u, &r);CHKERRQ(ierr); ierr = DMPlexSetSNESLocalFEM(dm,&user,&user,&user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); { Parameter *param; void *ctxs[2]; ierr = PetscBagGetData(user.bag, (void **) ¶m);CHKERRQ(ierr); ctxs[0] = ctxs[1] = param; ierr = DMProjectFunction(dm, 0.0, user.exactFuncs, ctxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, "Exact Solution");CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-exact_vec_view");CHKERRQ(ierr); } ierr = DMSNESCheckFromOptions(snes, u, NULL, NULL);CHKERRQ(ierr); ierr = VecSet(u, 0.0);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, "Solution");CHKERRQ(ierr); ierr = SNESSolve(snes, NULL, u);CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-sol_vec_view");CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = PetscFree(user.exactFuncs);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscBagDestroy(&user.bag);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
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); }
int main(int argc, char **argv) { AppCtx ctx; DM dm; TS ts; Vec u, r; PetscReal t = 0.0; PetscReal L2error = 0.0; PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL, help); CHKERRQ(ierr); ierr = ProcessOptions(PETSC_COMM_WORLD, &ctx); CHKERRQ(ierr); ierr = CreateMesh(PETSC_COMM_WORLD, &dm, &ctx); CHKERRQ(ierr); ierr = DMSetApplicationContext(dm, &ctx); CHKERRQ(ierr); ierr = PetscMalloc1(1, &ctx.exactFuncs); CHKERRQ(ierr); ierr = SetupDiscretization(dm, &ctx); CHKERRQ(ierr); ierr = DMCreateGlobalVector(dm, &u); CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, "temperature"); CHKERRQ(ierr); ierr = VecDuplicate(u, &r); CHKERRQ(ierr); ierr = TSCreate(PETSC_COMM_WORLD, &ts); CHKERRQ(ierr); ierr = TSSetDM(ts, dm); CHKERRQ(ierr); ierr = DMTSSetBoundaryLocal(dm, DMPlexTSComputeBoundary, &ctx); CHKERRQ(ierr); ierr = DMTSSetIFunctionLocal(dm, DMPlexTSComputeIFunctionFEM, &ctx); CHKERRQ(ierr); ierr = DMTSSetIJacobianLocal(dm, DMPlexTSComputeIJacobianFEM, &ctx); CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER); CHKERRQ(ierr); ierr = TSSetFromOptions(ts); CHKERRQ(ierr); ierr = DMProjectFunction(dm, t, ctx.exactFuncs, NULL, INSERT_ALL_VALUES, u); CHKERRQ(ierr); ierr = TSSolve(ts, u); CHKERRQ(ierr); ierr = TSGetTime(ts, &t); CHKERRQ(ierr); ierr = DMComputeL2Diff(dm, t, ctx.exactFuncs, NULL, u, &L2error); CHKERRQ(ierr); if (L2error < 1.0e-11) { ierr = PetscPrintf(PETSC_COMM_WORLD, "L_2 Error: < 1.0e-11\n"); CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD, "L_2 Error: %g\n", L2error); CHKERRQ(ierr); } ierr = VecViewFromOptions(u, NULL, "-sol_vec_view"); CHKERRQ(ierr); ierr = VecDestroy(&u); CHKERRQ(ierr); ierr = VecDestroy(&r); CHKERRQ(ierr); ierr = TSDestroy(&ts); CHKERRQ(ierr); ierr = DMDestroy(&dm); CHKERRQ(ierr); ierr = PetscFree(ctx.exactFuncs); CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc, char **argv) { MPI_Comm comm; DM base, preForest, postForest; PetscInt dim = 2; PetscInt preCount, postCount; Vec preVec, postVecTransfer, postVecExact; PetscErrorCode (*funcs[1]) (PetscInt,PetscReal,const PetscReal [],PetscInt,PetscScalar [], void *) = {MultiaffineFunction}; void *ctxs[1] = {NULL}; const PetscInt cells[] = {3, 3, 3}; PetscReal diff, tol = PETSC_SMALL; PetscBool linear = PETSC_FALSE; PetscBool useFV = PETSC_FALSE; PetscDS ds; bc_func_ctx bcCtx; DMLabel adaptLabel; PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr; comm = PETSC_COMM_WORLD; ierr = PetscOptionsBegin(comm, "", "DMForestTransferVec() Test Options", "DMFOREST");CHKERRQ(ierr); ierr = PetscOptionsInt("-dim", "The dimension (2 or 3)", "ex2.c", dim, &dim, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-linear","Transfer a simple linear function", "ex2.c", linear, &linear, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-use_fv","Use a finite volume approximation", "ex2.c", useFV, &useFV, NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); if (linear) { funcs[0] = LinearFunction; } bcCtx.func = funcs[0]; bcCtx.dim = dim; bcCtx.Nf = 1; bcCtx.ctx = NULL; /* the base mesh */ ierr = DMPlexCreateHexBoxMesh(comm, dim, cells, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, &base);CHKERRQ(ierr); if (useFV) { PetscFV fv; PetscLimiter limiter; DM baseFV; ierr = DMPlexConstructGhostCells(base,NULL,NULL,&baseFV);CHKERRQ(ierr); ierr = DMDestroy(&base);CHKERRQ(ierr); base = baseFV; ierr = PetscFVCreate(comm, &fv);CHKERRQ(ierr); ierr = PetscFVSetSpatialDimension(fv,dim);CHKERRQ(ierr); ierr = PetscFVSetType(fv,PETSCFVLEASTSQUARES);CHKERRQ(ierr); ierr = PetscFVSetNumComponents(fv,1);CHKERRQ(ierr); ierr = PetscLimiterCreate(comm,&limiter);CHKERRQ(ierr); ierr = PetscLimiterSetType(limiter,PETSCLIMITERNONE);CHKERRQ(ierr); ierr = PetscFVSetLimiter(fv,limiter);CHKERRQ(ierr); ierr = PetscLimiterDestroy(&limiter);CHKERRQ(ierr); ierr = PetscFVSetFromOptions(fv);CHKERRQ(ierr); ierr = DMSetField(base,0,(PetscObject)fv);CHKERRQ(ierr); ierr = PetscFVDestroy(&fv);CHKERRQ(ierr); } else { PetscFE fe; ierr = PetscFECreateDefault(base,dim,1,PETSC_FALSE,NULL,PETSC_DEFAULT,&fe);CHKERRQ(ierr); ierr = DMSetField(base,0,(PetscObject)fe);CHKERRQ(ierr); ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); } { PetscDS prob; PetscInt comps[] = {0}; PetscInt ids[] = {1, 2, 3, 4, 5, 6}; ierr = DMGetDS(base,&prob);CHKERRQ(ierr); ierr = PetscDSAddBoundary(prob,PETSC_TRUE, "bc", "marker", 0, 1, comps, useFV ? (void(*)()) bc_func_fv : (void(*)()) funcs[0], 2 * dim, ids, useFV ? (void *) &bcCtx : NULL);CHKERRQ(ierr); } ierr = AddIdentityLabel(base);CHKERRQ(ierr); ierr = DMViewFromOptions(base,NULL,"-dm_base_view");CHKERRQ(ierr); /* the pre adaptivity forest */ ierr = DMCreate(comm,&preForest);CHKERRQ(ierr); ierr = DMSetType(preForest,(dim == 2) ? DMP4EST : DMP8EST);CHKERRQ(ierr); ierr = DMGetDS(base,&ds);CHKERRQ(ierr); ierr = DMSetDS(preForest,ds);CHKERRQ(ierr); ierr = DMForestSetBaseDM(preForest,base);CHKERRQ(ierr); ierr = DMForestSetMinimumRefinement(preForest,1);CHKERRQ(ierr); ierr = DMForestSetInitialRefinement(preForest,1);CHKERRQ(ierr); ierr = DMSetFromOptions(preForest);CHKERRQ(ierr); ierr = DMSetUp(preForest);CHKERRQ(ierr); ierr = DMViewFromOptions(preForest,NULL,"-dm_pre_view");CHKERRQ(ierr); /* the pre adaptivity field */ ierr = DMCreateGlobalVector(preForest,&preVec);CHKERRQ(ierr); ierr = DMProjectFunction(preForest,0.,funcs,ctxs,INSERT_VALUES,preVec);CHKERRQ(ierr); ierr = VecViewFromOptions(preVec,NULL,"-vec_pre_view");CHKERRQ(ierr); ierr = PetscObjectGetReference((PetscObject)preForest,&preCount);CHKERRQ(ierr); /* adapt */ ierr = CreateAdaptivityLabel(preForest,&adaptLabel);CHKERRQ(ierr); ierr = DMForestTemplate(preForest,comm,&postForest);CHKERRQ(ierr); ierr = DMForestSetMinimumRefinement(postForest,0);CHKERRQ(ierr); ierr = DMForestSetInitialRefinement(postForest,0);CHKERRQ(ierr); ierr = DMForestSetAdaptivityLabel(postForest,adaptLabel);CHKERRQ(ierr); ierr = DMLabelDestroy(&adaptLabel);CHKERRQ(ierr); ierr = DMSetUp(postForest);CHKERRQ(ierr); ierr = DMViewFromOptions(postForest,NULL,"-dm_post_view");CHKERRQ(ierr); /* transfer */ ierr = DMCreateGlobalVector(postForest,&postVecTransfer);CHKERRQ(ierr); ierr = DMForestTransferVec(preForest,preVec,postForest,postVecTransfer,PETSC_TRUE,0.0);CHKERRQ(ierr); ierr = VecViewFromOptions(postVecTransfer,NULL,"-vec_post_transfer_view");CHKERRQ(ierr); /* the exact post adaptivity field */ ierr = DMCreateGlobalVector(postForest,&postVecExact);CHKERRQ(ierr); ierr = DMProjectFunction(postForest,0.,funcs,ctxs,INSERT_VALUES,postVecExact);CHKERRQ(ierr); ierr = VecViewFromOptions(postVecExact,NULL,"-vec_post_exact_view");CHKERRQ(ierr); /* compare */ ierr = VecAXPY(postVecTransfer,-1.,postVecExact);CHKERRQ(ierr); ierr = VecViewFromOptions(postVecTransfer,NULL,"-vec_diff_view");CHKERRQ(ierr); ierr = VecNorm(postVecTransfer,NORM_2,&diff);CHKERRQ(ierr); /* output */ if (diff < tol) { ierr = PetscPrintf(comm,"DMForestTransferVec() passes.\n");CHKERRQ(ierr); } else { ierr = PetscPrintf(comm,"DMForestTransferVec() fails with error %g and tolerance %g\n",diff,tol);CHKERRQ(ierr); } /* disconnect preForest from postForest */ ierr = DMForestSetAdaptivityForest(postForest,NULL);CHKERRQ(ierr); ierr = PetscObjectGetReference((PetscObject)preForest,&postCount);CHKERRQ(ierr); if (postCount != preCount) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptation not memory neutral: reference count increase from %d to %d\n",preCount,postCount); /* cleanup */ ierr = VecDestroy(&postVecExact);CHKERRQ(ierr); ierr = VecDestroy(&postVecTransfer);CHKERRQ(ierr); ierr = DMDestroy(&postForest);CHKERRQ(ierr); ierr = VecDestroy(&preVec);CHKERRQ(ierr); ierr = DMDestroy(&preForest);CHKERRQ(ierr); ierr = DMDestroy(&base);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
/*@ PetscConvEstGetConvRate - Returns an estimate of the convergence rate for the discretization Not collective Input Parameter: . ce - The PetscConvEst object Output Parameter: . alpha - The convergence rate for each field Note: The convergence rate alpha is defined by $ || u_h - u_exact || < C h^alpha where u_h is the discrete solution, and h is a measure of the discretization size. We solve a series of problems on refined meshes, calculate an error based upon the exact solution in the DS, and then fit the result to our model above using linear regression. Options database keys: . -snes_convergence_estimate : Execute convergence estimation and print out the rate Level: intermediate .keywords: PetscConvEst, convergence .seealso: PetscConvEstSetSolver(), PetscConvEstCreate(), PetscConvEstGetConvRate() @*/ PetscErrorCode PetscConvEstGetConvRate(PetscConvEst ce, PetscReal alpha[]) { DM *dm; PetscObject disc; MPI_Comm comm; const char *uname, *dmname; void *ctx; Vec u; PetscReal t = 0.0, *x, *y, slope, intercept; PetscInt *dof, dim, Nr = ce->Nr, r, f, oldlevel, oldnlev; PetscLogEvent event; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject) ce, &comm);CHKERRQ(ierr); ierr = DMGetDimension(ce->idm, &dim);CHKERRQ(ierr); ierr = DMGetApplicationContext(ce->idm, &ctx);CHKERRQ(ierr); ierr = DMPlexSetRefinementUniform(ce->idm, PETSC_TRUE);CHKERRQ(ierr); ierr = DMGetRefineLevel(ce->idm, &oldlevel);CHKERRQ(ierr); ierr = PetscMalloc2((Nr+1), &dm, (Nr+1)*ce->Nf, &dof);CHKERRQ(ierr); dm[0] = ce->idm; for (f = 0; f < ce->Nf; ++f) alpha[f] = 0.0; /* Loop over meshes */ ierr = PetscLogEventRegister("ConvEst Error", PETSC_OBJECT_CLASSID, &event);CHKERRQ(ierr); for (r = 0; r <= Nr; ++r) { PetscLogStage stage; char stageName[PETSC_MAX_PATH_LEN]; ierr = PetscSNPrintf(stageName, PETSC_MAX_PATH_LEN-1, "ConvEst Refinement Level %D", r);CHKERRQ(ierr); ierr = PetscLogStageRegister(stageName, &stage);CHKERRQ(ierr); ierr = PetscLogStagePush(stage);CHKERRQ(ierr); if (r > 0) { ierr = DMRefine(dm[r-1], MPI_COMM_NULL, &dm[r]);CHKERRQ(ierr); ierr = DMSetCoarseDM(dm[r], dm[r-1]);CHKERRQ(ierr); ierr = DMCopyDisc(ce->idm, dm[r]);CHKERRQ(ierr); ierr = DMCopyTransform(ce->idm, dm[r]);CHKERRQ(ierr); ierr = PetscObjectGetName((PetscObject) dm[r-1], &dmname);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) dm[r], dmname);CHKERRQ(ierr); for (f = 0; f <= ce->Nf; ++f) { PetscErrorCode (*nspconstr)(DM, PetscInt, MatNullSpace *); ierr = DMGetNullSpaceConstructor(dm[r-1], f, &nspconstr);CHKERRQ(ierr); ierr = DMSetNullSpaceConstructor(dm[r], f, nspconstr);CHKERRQ(ierr); } } ierr = DMViewFromOptions(dm[r], NULL, "-conv_dm_view");CHKERRQ(ierr); /* Create solution */ ierr = DMCreateGlobalVector(dm[r], &u);CHKERRQ(ierr); ierr = DMGetField(dm[r], 0, NULL, &disc);CHKERRQ(ierr); ierr = PetscObjectGetName(disc, &uname);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, uname);CHKERRQ(ierr); /* Setup solver */ ierr = SNESReset(ce->snes);CHKERRQ(ierr); ierr = SNESSetDM(ce->snes, dm[r]);CHKERRQ(ierr); ierr = DMPlexSetSNESLocalFEM(dm[r], ctx, ctx, ctx);CHKERRQ(ierr); ierr = SNESSetFromOptions(ce->snes);CHKERRQ(ierr); /* Create initial guess */ ierr = DMProjectFunction(dm[r], t, ce->initGuess, ce->ctxs, INSERT_VALUES, u);CHKERRQ(ierr); ierr = SNESSolve(ce->snes, NULL, u);CHKERRQ(ierr); ierr = PetscLogEventBegin(event, ce, 0, 0, 0);CHKERRQ(ierr); ierr = DMComputeL2FieldDiff(dm[r], t, ce->exactSol, ce->ctxs, u, &ce->errors[r*ce->Nf]);CHKERRQ(ierr); ierr = PetscLogEventEnd(event, ce, 0, 0, 0);CHKERRQ(ierr); for (f = 0; f < ce->Nf; ++f) { PetscSection s, fs; PetscInt lsize; /* Could use DMGetOutputDM() to add in Dirichlet dofs */ ierr = DMGetSection(dm[r], &s);CHKERRQ(ierr); ierr = PetscSectionGetField(s, f, &fs);CHKERRQ(ierr); ierr = PetscSectionGetConstrainedStorageSize(fs, &lsize);CHKERRQ(ierr); ierr = MPI_Allreduce(&lsize, &dof[r*ce->Nf+f], 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) ce->snes));CHKERRQ(ierr); ierr = PetscLogEventSetDof(event, f, dof[r*ce->Nf+f]);CHKERRQ(ierr); ierr = PetscLogEventSetError(event, f, ce->errors[r*ce->Nf+f]);CHKERRQ(ierr); } /* Monitor */ if (ce->monitor) { PetscReal *errors = &ce->errors[r*ce->Nf]; ierr = PetscPrintf(comm, "L_2 Error: ");CHKERRQ(ierr); if (ce->Nf > 1) {ierr = PetscPrintf(comm, "[");CHKERRQ(ierr);} for (f = 0; f < ce->Nf; ++f) { if (f > 0) {ierr = PetscPrintf(comm, ", ");CHKERRQ(ierr);} if (errors[f] < 1.0e-11) {ierr = PetscPrintf(comm, "< 1e-11");CHKERRQ(ierr);} else {ierr = PetscPrintf(comm, "%g", (double)errors[f]);CHKERRQ(ierr);} } if (ce->Nf > 1) {ierr = PetscPrintf(comm, "]");CHKERRQ(ierr);} ierr = PetscPrintf(comm, "\n");CHKERRQ(ierr); } if (!r) { /* PCReset() does not wipe out the level structure */ KSP ksp; PC pc; ierr = SNESGetKSP(ce->snes, &ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); ierr = PCMGGetLevels(pc, &oldnlev);CHKERRQ(ierr); } /* Cleanup */ ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); } for (r = 1; r <= Nr; ++r) { ierr = DMDestroy(&dm[r]);CHKERRQ(ierr); } /* Fit convergence rate */ ierr = PetscMalloc2(Nr+1, &x, Nr+1, &y);CHKERRQ(ierr); for (f = 0; f < ce->Nf; ++f) { for (r = 0; r <= Nr; ++r) { x[r] = PetscLog10Real(dof[r*ce->Nf+f]); y[r] = PetscLog10Real(ce->errors[r*ce->Nf+f]); } ierr = PetscLinearRegression(Nr+1, x, y, &slope, &intercept);CHKERRQ(ierr); /* Since h^{-dim} = N, lg err = s lg N + b = -s dim lg h + b */ alpha[f] = -slope * dim; } ierr = PetscFree2(x, y);CHKERRQ(ierr); ierr = PetscFree2(dm, dof);CHKERRQ(ierr); /* Restore solver */ ierr = SNESReset(ce->snes);CHKERRQ(ierr); { /* PCReset() does not wipe out the level structure */ KSP ksp; PC pc; ierr = SNESGetKSP(ce->snes, &ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); ierr = PCMGSetLevels(pc, oldnlev, NULL);CHKERRQ(ierr); ierr = DMSetRefineLevel(ce->idm, oldlevel);CHKERRQ(ierr); /* The damn DMCoarsen() calls in PCMG can reset this */ } ierr = SNESSetDM(ce->snes, ce->idm);CHKERRQ(ierr); ierr = DMPlexSetSNESLocalFEM(ce->idm, ctx, ctx, ctx);CHKERRQ(ierr); ierr = SNESSetFromOptions(ce->snes);CHKERRQ(ierr); PetscFunctionReturn(0); }