int main(int argc, char **argv) { DM dm, subdm, auxdm; Vec la; AppCtx user; PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr; ierr = ProcessOptions(&user);CHKERRQ(ierr); ierr = CreateMesh(PETSC_COMM_WORLD, &user, &dm);CHKERRQ(ierr); ierr = SetupDiscretization(dm, user.dim, user.cellSimplex, &user);CHKERRQ(ierr); /* Volumetric Mesh Projection */ ierr = TestFunctionProjection(dm, NULL, NULL, NULL, "Volumetric Primary", &user);CHKERRQ(ierr); ierr = TestFieldProjection(dm, NULL, NULL, NULL, "Volumetric Primary", &user);CHKERRQ(ierr); if (user.auxfield) { /* Volumetric Mesh Projection with Volumetric Data */ ierr = CreateAuxiliaryData(dm, &auxdm, &la, &user);CHKERRQ(ierr); ierr = TestFunctionProjection(dm, auxdm, NULL, la, "Volumetric Primary and Volumetric Auxiliary", &user);CHKERRQ(ierr); ierr = TestFieldProjection(dm, auxdm, NULL, la, "Volumetric Primary and Volumetric Auxiliary", &user);CHKERRQ(ierr); ierr = VecDestroy(&la);CHKERRQ(ierr); /* Update of Volumetric Auxiliary Data with primary Volumetric Data */ ierr = DMGetLocalVector(dm, &la);CHKERRQ(ierr); ierr = VecSet(la, 1.0);CHKERRQ(ierr); ierr = TestFieldProjection(auxdm, dm, NULL, la, "Volumetric Auxiliary Update with Volumetric Primary", &user);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm, &la);CHKERRQ(ierr); ierr = DMDestroy(&auxdm);CHKERRQ(ierr); } if (user.submesh) { DMLabel bdLabel; /* Boundary Mesh Projection */ ierr = CreateBoundaryMesh(dm, &bdLabel, &subdm, &user);CHKERRQ(ierr); ierr = TestFunctionProjection(subdm, NULL, NULL, NULL, "Boundary Primary", &user);CHKERRQ(ierr); ierr = TestFieldProjection(subdm, NULL, NULL, NULL, "Boundary Primary", &user);CHKERRQ(ierr); if (user.auxfield) { /* Boundary Mesh Projection with Boundary Data */ ierr = CreateAuxiliaryData(subdm, &auxdm, &la, &user);CHKERRQ(ierr); ierr = TestFunctionProjection(subdm, auxdm, NULL, la, "Boundary Primary and Boundary Auxiliary", &user);CHKERRQ(ierr); ierr = TestFieldProjection(subdm, auxdm, NULL, la, "Boundary Primary and Boundary Auxiliary", &user);CHKERRQ(ierr); ierr = VecDestroy(&la);CHKERRQ(ierr); ierr = DMDestroy(&auxdm);CHKERRQ(ierr); /* Volumetric Mesh Projection with Boundary Data */ ierr = CreateAuxiliaryData(subdm, &auxdm, &la, &user);CHKERRQ(ierr); ierr = TestFunctionProjection(dm, auxdm, bdLabel, la, "Volumetric Primary and Boundary Auxiliary", &user);CHKERRQ(ierr); ierr = TestFieldProjection(dm, auxdm, bdLabel, la, "Volumetric Primary and Boundary Auxiliary", &user);CHKERRQ(ierr); ierr = VecDestroy(&la);CHKERRQ(ierr); ierr = DMDestroy(&auxdm);CHKERRQ(ierr); } ierr = DMLabelDestroy(&bdLabel);CHKERRQ(ierr); ierr = DMDestroy(&subdm);CHKERRQ(ierr); } ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
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; }
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; }
static PetscErrorCode CreateBoundaryMesh(DM dm, DMLabel *bdLabel, DM *subdm, AppCtx *user) { DMLabel label; PetscInt dim; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = DMLabelCreate(PETSC_COMM_SELF, "sub", &label);CHKERRQ(ierr); ierr = DMPlexMarkBoundaryFaces(dm, 1, label);CHKERRQ(ierr); ierr = DMPlexLabelComplete(dm, label);CHKERRQ(ierr); ierr = DMPlexCreateSubmesh(dm, label, 1, PETSC_TRUE, subdm);CHKERRQ(ierr); ierr = DMGetDimension(*subdm, &dim);CHKERRQ(ierr); ierr = SetupDiscretization(*subdm, dim, user->cellSimplex, user);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) *subdm, "boundary");CHKERRQ(ierr); ierr = DMViewFromOptions(*subdm, NULL, "-sub_dm_view");CHKERRQ(ierr); if (bdLabel) *bdLabel = label; else ierr = DMLabelDestroy(&label);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode CreateAuxiliaryData(DM dm, DM *auxdm, Vec *la, AppCtx *user) { PetscErrorCode (**afuncs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *); PetscInt dim, Nf, f; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); ierr = PetscMalloc1(Nf, &afuncs);CHKERRQ(ierr); for (f = 0; f < Nf; ++f) afuncs[f] = linear; ierr = DMClone(dm, auxdm);CHKERRQ(ierr); ierr = SetupDiscretization(*auxdm, dim, user->cellSimplex, user);CHKERRQ(ierr); ierr = DMCreateLocalVector(*auxdm, la);CHKERRQ(ierr); ierr = DMProjectFunctionLocal(dm, 0.0, afuncs, NULL, INSERT_VALUES, *la);CHKERRQ(ierr); ierr = VecViewFromOptions(*la, NULL, "-local_aux_view");CHKERRQ(ierr); ierr = PetscFree(afuncs);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) { DM dm; /* Problem specification */ SNES snes; /* Nonlinear solver */ Vec u; /* Solutions */ 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); /* Primal system */ ierr = SNESCreate(PETSC_COMM_WORLD, &snes);CHKERRQ(ierr); ierr = CreateMesh(PETSC_COMM_WORLD, &user, &dm);CHKERRQ(ierr); ierr = SNESSetDM(snes, dm);CHKERRQ(ierr); ierr = SetupDiscretization(dm, "potential", SetupPrimalProblem, &user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dm, &u);CHKERRQ(ierr); ierr = VecSet(u, 0.0);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, "potential");CHKERRQ(ierr); ierr = DMPlexSetSNESLocalFEM(dm, &user, &user, &user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes, NULL, u);CHKERRQ(ierr); ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-potential_view");CHKERRQ(ierr); if (user.spectral) { PetscInt planeDir[2] = {0, 1}; PetscReal planeCoord[2] = {0., 1.}; ierr = ComputeSpectral(dm, u, 2, planeDir, planeCoord, &user);CHKERRQ(ierr); } /* Adjoint system */ if (user.adjoint) { DM dmAdj; SNES snesAdj; Vec uAdj; ierr = SNESCreate(PETSC_COMM_WORLD, &snesAdj);CHKERRQ(ierr); ierr = PetscObjectSetOptionsPrefix((PetscObject) snesAdj, "adjoint_");CHKERRQ(ierr); ierr = DMClone(dm, &dmAdj);CHKERRQ(ierr); ierr = SNESSetDM(snesAdj, dmAdj);CHKERRQ(ierr); ierr = SetupDiscretization(dmAdj, "adjoint", SetupAdjointProblem, &user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dmAdj, &uAdj);CHKERRQ(ierr); ierr = VecSet(uAdj, 0.0);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) uAdj, "adjoint");CHKERRQ(ierr); ierr = DMPlexSetSNESLocalFEM(dmAdj, &user, &user, &user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snesAdj);CHKERRQ(ierr); ierr = SNESSolve(snesAdj, NULL, uAdj);CHKERRQ(ierr); ierr = SNESGetSolution(snesAdj, &uAdj);CHKERRQ(ierr); ierr = VecViewFromOptions(uAdj, NULL, "-adjoint_view");CHKERRQ(ierr); /* Error representation */ { DM dmErr, dmErrAux, dms[2]; Vec errorEst, errorL2, uErr, uErrLoc, uAdjLoc, uAdjProj; IS *subis; PetscReal errorEstTot, errorL2Norm, errorL2Tot; PetscInt N, i; PetscErrorCode (*funcs[1])(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *) = {trig_u}; void (*identity[1])(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]) = {f0_identityaux_u}; void *ctxs[1] = {0}; ctxs[0] = &user; ierr = DMClone(dm, &dmErr);CHKERRQ(ierr); ierr = SetupDiscretization(dmErr, "error", SetupErrorProblem, &user);CHKERRQ(ierr); ierr = DMGetGlobalVector(dmErr, &errorEst);CHKERRQ(ierr); ierr = DMGetGlobalVector(dmErr, &errorL2);CHKERRQ(ierr); /* Compute auxiliary data (solution and projection of adjoint solution) */ ierr = DMGetLocalVector(dmAdj, &uAdjLoc);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dmAdj, uAdj, INSERT_VALUES, uAdjLoc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dmAdj, uAdj, INSERT_VALUES, uAdjLoc);CHKERRQ(ierr); ierr = DMGetGlobalVector(dm, &uAdjProj);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "dmAux", (PetscObject) dmAdj);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "A", (PetscObject) uAdjLoc);CHKERRQ(ierr); ierr = DMProjectField(dm, 0.0, u, identity, INSERT_VALUES, uAdjProj);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "dmAux", NULL);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "A", NULL);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dmAdj, &uAdjLoc);CHKERRQ(ierr); /* Attach auxiliary data */ dms[0] = dm; dms[1] = dm; ierr = DMCreateSuperDM(dms, 2, &subis, &dmErrAux);CHKERRQ(ierr); if (0) { PetscSection sec; ierr = DMGetSection(dms[0], &sec);CHKERRQ(ierr); ierr = PetscSectionView(sec, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMGetSection(dms[1], &sec);CHKERRQ(ierr); ierr = PetscSectionView(sec, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMGetSection(dmErrAux, &sec);CHKERRQ(ierr); ierr = PetscSectionView(sec, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = DMViewFromOptions(dmErrAux, NULL, "-dm_err_view");CHKERRQ(ierr); ierr = ISViewFromOptions(subis[0], NULL, "-super_is_view");CHKERRQ(ierr); ierr = ISViewFromOptions(subis[1], NULL, "-super_is_view");CHKERRQ(ierr); ierr = DMGetGlobalVector(dmErrAux, &uErr);CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-map_vec_view");CHKERRQ(ierr); ierr = VecViewFromOptions(uAdjProj, NULL, "-map_vec_view");CHKERRQ(ierr); ierr = VecViewFromOptions(uErr, NULL, "-map_vec_view");CHKERRQ(ierr); ierr = VecISCopy(uErr, subis[0], SCATTER_FORWARD, u);CHKERRQ(ierr); ierr = VecISCopy(uErr, subis[1], SCATTER_FORWARD, uAdjProj);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dm, &uAdjProj);CHKERRQ(ierr); for (i = 0; i < 2; ++i) {ierr = ISDestroy(&subis[i]);CHKERRQ(ierr);} ierr = PetscFree(subis);CHKERRQ(ierr); ierr = DMGetLocalVector(dmErrAux, &uErrLoc);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm, uErr, INSERT_VALUES, uErrLoc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm, uErr, INSERT_VALUES, uErrLoc);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dmErrAux, &uErr);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmAdj, "dmAux", (PetscObject) dmErrAux);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmAdj, "A", (PetscObject) uErrLoc);CHKERRQ(ierr); /* Compute cellwise error estimate */ ierr = VecSet(errorEst, 0.0);CHKERRQ(ierr); ierr = DMPlexComputeCellwiseIntegralFEM(dmAdj, uAdj, errorEst, &user);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmAdj, "dmAux", NULL);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmAdj, "A", NULL);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dmErrAux, &uErrLoc);CHKERRQ(ierr); ierr = DMDestroy(&dmErrAux);CHKERRQ(ierr); /* Plot cellwise error vector */ ierr = VecViewFromOptions(errorEst, NULL, "-error_view");CHKERRQ(ierr); /* Compute ratio of estimate (sum over cells) with actual L_2 error */ ierr = DMComputeL2Diff(dm, 0.0, funcs, ctxs, u, &errorL2Norm);CHKERRQ(ierr); ierr = DMPlexComputeL2DiffVec(dm, 0.0, funcs, ctxs, u, errorL2);CHKERRQ(ierr); ierr = VecViewFromOptions(errorL2, NULL, "-l2_error_view");CHKERRQ(ierr); ierr = VecNorm(errorL2, NORM_INFINITY, &errorL2Tot);CHKERRQ(ierr); ierr = VecNorm(errorEst, NORM_INFINITY, &errorEstTot);CHKERRQ(ierr); ierr = VecGetSize(errorEst, &N);CHKERRQ(ierr); ierr = VecPointwiseDivide(errorEst, errorEst, errorL2);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) errorEst, "Error ratio");CHKERRQ(ierr); ierr = VecViewFromOptions(errorEst, NULL, "-error_ratio_view");CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "N: %D L2 error: %g Error Ratio: %g/%g = %g\n", N, (double) errorL2Norm, (double) errorEstTot, (double) PetscSqrtReal(errorL2Tot), (double) errorEstTot/PetscSqrtReal(errorL2Tot));CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dmErr, &errorEst);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dmErr, &errorL2);CHKERRQ(ierr); ierr = DMDestroy(&dmErr);CHKERRQ(ierr); } ierr = DMDestroy(&dmAdj);CHKERRQ(ierr); ierr = VecDestroy(&uAdj);CHKERRQ(ierr); ierr = SNESDestroy(&snesAdj);CHKERRQ(ierr); } /* Cleanup */ ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc, char **argv) { DM dm; /* Problem specification */ SNES snes; /* nonlinear solver */ Vec u,r; /* solution, residual vectors */ Mat A,J; /* Jacobian matrix */ MatNullSpace nullSpace; /* May be necessary for Neumann conditions */ AppCtx user; /* user-defined work context */ JacActionCtx userJ; /* context for Jacobian MF action */ PetscInt its; /* iterations for convergence */ PetscReal error = 0.0; /* L_2 error in the solution */ 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 = DMSetApplicationContext(dm, &user);CHKERRQ(ierr); ierr = PetscMalloc(1 * sizeof(void (*)(const PetscReal[], PetscScalar *, void *)), &user.exactFuncs);CHKERRQ(ierr); ierr = SetupDiscretization(dm, &user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dm, &u);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, "potential");CHKERRQ(ierr); ierr = VecDuplicate(u, &r);CHKERRQ(ierr); ierr = DMSetMatType(dm,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(dm, &J);CHKERRQ(ierr); if (user.jacobianMF) { PetscInt M, m, N, n; ierr = MatGetSize(J, &M, &N);CHKERRQ(ierr); ierr = MatGetLocalSize(J, &m, &n);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD, &A);CHKERRQ(ierr); ierr = MatSetSizes(A, m, n, M, N);CHKERRQ(ierr); ierr = MatSetType(A, MATSHELL);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); #if 0 ierr = MatShellSetOperation(A, MATOP_MULT, (void (*)(void))FormJacobianAction);CHKERRQ(ierr); #endif userJ.dm = dm; userJ.J = J; userJ.user = &user; ierr = DMCreateLocalVector(dm, &userJ.u);CHKERRQ(ierr); ierr = DMPlexProjectFunctionLocal(dm, user.exactFuncs, NULL, INSERT_BC_VALUES, userJ.u);CHKERRQ(ierr); ierr = MatShellSetContext(A, &userJ);CHKERRQ(ierr); } else { A = J; } if (user.bcType == NEUMANN) { ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject) dm), PETSC_TRUE, 0, NULL, &nullSpace);CHKERRQ(ierr); ierr = MatSetNullSpace(J, nullSpace);CHKERRQ(ierr); if (A != J) { ierr = MatSetNullSpace(A, nullSpace);CHKERRQ(ierr); } } ierr = DMSNESSetFunctionLocal(dm, (PetscErrorCode (*)(DM,Vec,Vec,void*)) DMPlexSNESComputeResidualFEM, &user);CHKERRQ(ierr); ierr = DMSNESSetJacobianLocal(dm, (PetscErrorCode (*)(DM,Vec,Mat,Mat,void*)) DMPlexSNESComputeJacobianFEM, &user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes, A, J, NULL, NULL);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = DMPlexProjectFunction(dm, user.exactFuncs, NULL, INSERT_ALL_VALUES, u);CHKERRQ(ierr); if (user.checkpoint) { #if defined(PETSC_HAVE_HDF5) ierr = PetscViewerHDF5PushGroup(user.checkpoint, "/fields");CHKERRQ(ierr); ierr = VecLoad(u, user.checkpoint);CHKERRQ(ierr); ierr = PetscViewerHDF5PopGroup(user.checkpoint);CHKERRQ(ierr); #endif } ierr = PetscViewerDestroy(&user.checkpoint);CHKERRQ(ierr); if (user.showInitial) { Vec lv; ierr = DMGetLocalVector(dm, &lv);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm, u, INSERT_VALUES, lv);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm, u, INSERT_VALUES, lv);CHKERRQ(ierr); ierr = DMPrintLocalVec(dm, "Local function", 1.0e-10, lv);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm, &lv);CHKERRQ(ierr); } if (user.runType == RUN_FULL) { void (*initialGuess[1])(const PetscReal x[], PetscScalar *, void *ctx) = {zero}; ierr = DMPlexProjectFunction(dm, initialGuess, NULL, INSERT_VALUES, u);CHKERRQ(ierr); if (user.debug) { ierr = PetscPrintf(PETSC_COMM_WORLD, "Initial guess\n");CHKERRQ(ierr); ierr = VecView(u, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = SNESSolve(snes, NULL, u);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes, &its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Number of SNES iterations = %D\n", its);CHKERRQ(ierr); ierr = DMPlexComputeL2Diff(dm, user.exactFuncs, NULL, u, &error);CHKERRQ(ierr); if (error < 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", error);CHKERRQ(ierr);} if (user.showSolution) { ierr = PetscPrintf(PETSC_COMM_WORLD, "Solution\n");CHKERRQ(ierr); ierr = VecChop(u, 3.0e-9);CHKERRQ(ierr); ierr = VecView(u, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } } else if (user.runType == RUN_PERF) { PetscReal res = 0.0; ierr = SNESComputeFunction(snes, u, r);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Initial Residual\n");CHKERRQ(ierr); ierr = VecChop(r, 1.0e-10);CHKERRQ(ierr); ierr = VecNorm(r, NORM_2, &res);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "L_2 Residual: %g\n", res);CHKERRQ(ierr); } else { PetscReal res = 0.0; /* Check discretization error */ ierr = PetscPrintf(PETSC_COMM_WORLD, "Initial guess\n");CHKERRQ(ierr); ierr = VecView(u, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMPlexComputeL2Diff(dm, user.exactFuncs, NULL, u, &error);CHKERRQ(ierr); if (error < 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", error);CHKERRQ(ierr);} /* Check residual */ ierr = SNESComputeFunction(snes, u, r);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Initial Residual\n");CHKERRQ(ierr); ierr = VecChop(r, 1.0e-10);CHKERRQ(ierr); ierr = VecView(r, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecNorm(r, NORM_2, &res);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "L_2 Residual: %g\n", res);CHKERRQ(ierr); /* Check Jacobian */ { Vec b; ierr = SNESComputeJacobian(snes, u, A, A);CHKERRQ(ierr); ierr = VecDuplicate(u, &b);CHKERRQ(ierr); ierr = VecSet(r, 0.0);CHKERRQ(ierr); ierr = SNESComputeFunction(snes, r, b);CHKERRQ(ierr); ierr = MatMult(A, u, r);CHKERRQ(ierr); ierr = VecAXPY(r, 1.0, b);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Au - b = Au + F(0)\n");CHKERRQ(ierr); ierr = VecChop(r, 1.0e-10);CHKERRQ(ierr); ierr = VecView(r, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecNorm(r, NORM_2, &res);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Linear L_2 Residual: %g\n", res);CHKERRQ(ierr); } } ierr = VecViewFromOptions(u, NULL, "-vec_view");CHKERRQ(ierr); if (user.bcType == NEUMANN) {ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr);} if (user.jacobianMF) {ierr = VecDestroy(&userJ.u);CHKERRQ(ierr);} if (A != J) {ierr = MatDestroy(&A);CHKERRQ(ierr);} ierr = MatDestroy(&J);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; }