Actual source code: ex26.c
1: static char help[] = "Solves the trivial ODE 2 du/dt = 1, u(0) = 0. \n\n";
3: #include <petscts.h>
4: #include <petscpc.h>
6: PetscErrorCode IFunction(TS, PetscReal, Vec, Vec, Vec, void *);
7: PetscErrorCode IJacobian(TS, PetscReal, Vec, Vec, PetscReal, Mat, Mat, void *);
8: PetscErrorCode RHSFunction(TS, PetscReal, Vec, Vec, void *);
10: int main(int argc, char **argv)
11: {
12: TS ts;
13: Vec x;
14: Mat A;
15: PetscBool flg = PETSC_FALSE, usingimex;
17: PetscFunctionBeginUser;
18: PetscCall(PetscInitialize(&argc, &argv, NULL, help));
20: PetscCall(TSCreate(PETSC_COMM_WORLD, &ts));
21: PetscCall(PetscOptionsGetBool(NULL, NULL, "-set_implicit", &flg, NULL));
22: if (flg) PetscCall(TSSetEquationType(ts, TS_EQ_ODE_IMPLICIT));
23: PetscCall(TSSetIFunction(ts, NULL, IFunction, NULL));
24: PetscCall(TSSetRHSFunction(ts, NULL, RHSFunction, &usingimex));
26: PetscCall(MatCreate(PETSC_COMM_WORLD, &A));
27: PetscCall(MatSetSizes(A, 1, 1, PETSC_DECIDE, PETSC_DECIDE));
28: PetscCall(MatSetFromOptions(A));
29: PetscCall(MatSetUp(A));
30: PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
31: PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
32: PetscCall(TSSetIJacobian(ts, A, A, IJacobian, NULL));
33: PetscCall(MatDestroy(&A));
35: PetscCall(VecCreate(PETSC_COMM_WORLD, &x));
36: PetscCall(VecSetSizes(x, 1, PETSC_DECIDE));
37: PetscCall(VecSetFromOptions(x));
38: PetscCall(VecSetUp(x));
39: PetscCall(TSSetSolution(ts, x));
40: PetscCall(VecDestroy(&x));
41: PetscCall(TSSetFromOptions(ts));
43: /* Need to know if we are using an IMEX scheme to decide on the form
44: of the RHS function */
45: PetscCall(PetscObjectTypeCompare((PetscObject)ts, TSARKIMEX, &usingimex));
46: if (usingimex) {
47: PetscCall(TSARKIMEXGetFullyImplicit(ts, &flg));
48: if (flg) usingimex = PETSC_FALSE;
49: }
50: PetscCall(TSSetStepNumber(ts, 0));
51: PetscCall(TSSetTimeStep(ts, 1));
52: PetscCall(TSSetTime(ts, 0));
53: PetscCall(TSSetMaxTime(ts, PETSC_MAX_REAL));
54: PetscCall(TSSetMaxSteps(ts, 3));
56: PetscCall(TSSolve(ts, NULL));
58: PetscCall(TSDestroy(&ts));
59: PetscCall(PetscFinalize());
60: return 0;
61: }
63: PetscErrorCode RHSFunction(TS ts, PetscReal t, Vec x, Vec f, void *ctx)
64: {
65: PetscBool usingimex = *(PetscBool *)ctx;
67: PetscFunctionBeginUser;
68: PetscCall(VecSet(f, usingimex ? 0.5 : 1));
69: PetscFunctionReturn(PETSC_SUCCESS);
70: }
72: PetscErrorCode IFunction(TS ts, PetscReal t, Vec x, Vec xdot, Vec f, void *ctx)
73: {
74: PetscFunctionBeginUser;
75: PetscCall(VecCopy(xdot, f));
76: PetscCall(VecScale(f, 2.0));
77: PetscFunctionReturn(PETSC_SUCCESS);
78: }
80: PetscErrorCode IJacobian(TS ts, PetscReal t, Vec x, Vec xdot, PetscReal shift, Mat A, Mat B, void *ctx)
81: {
82: PetscScalar j;
84: PetscFunctionBeginUser;
85: j = shift * 2.0;
86: PetscCall(MatSetValue(B, 0, 0, j, INSERT_VALUES));
87: PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
88: PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
89: PetscFunctionReturn(PETSC_SUCCESS);
90: }
92: /*TEST
94: test:
95: suffix: arkimex_explicit_stage
96: requires: !defined(PETSCTEST_VALGRIND) defined(PETSC_USE_DEBUG) !defined(PETSC_HAVE_SANITIZER)
97: args: -ts_type arkimex -petsc_ci_portable_error_output -error_output_stdout -set_implicit
98: filter: grep -E -v "(memory block|leaked context|not freed before MPI_Finalize|Could be the program crashed)"
100: test:
101: suffix: arkimex_implicit_stage
102: args: -ts_type arkimex -ts_arkimex_type {{3 l2}} -ts_monitor_solution -ts_monitor
104: TEST*/