Actual source code: ex6.c
1: static char help[] = "Solves DAE with integrator only on non-algebraic terms \n";
3: #include <petscts.h>
5: /*
6: \dot{U} = f(U,V)
7: F(U,V) = 0
8: */
10: /*
11: f(U,V) = U + V
12: */
13: PetscErrorCode f(PetscReal t, Vec U, Vec V, Vec F)
14: {
15: PetscFunctionBeginUser;
16: PetscCall(VecWAXPY(F, 1.0, U, V));
17: PetscFunctionReturn(PETSC_SUCCESS);
18: }
20: /*
21: F(U,V) = U - V
22: */
23: PetscErrorCode F(PetscReal t, Vec U, Vec V, Vec F)
24: {
25: PetscFunctionBeginUser;
26: PetscCall(VecWAXPY(F, -1.0, V, U));
27: PetscFunctionReturn(PETSC_SUCCESS);
28: }
30: typedef struct {
31: PetscReal t;
32: SNES snes;
33: Vec U, V;
34: PetscErrorCode (*f)(PetscReal, Vec, Vec, Vec);
35: PetscErrorCode (*F)(PetscReal, Vec, Vec, Vec);
36: } AppCtx;
38: extern PetscErrorCode TSFunction(TS, PetscReal, Vec, Vec, void *);
39: extern PetscErrorCode SNESFunction(SNES, Vec, Vec, void *);
41: int main(int argc, char **argv)
42: {
43: AppCtx ctx;
44: TS ts;
45: Vec tsrhs, U;
47: PetscFunctionBeginUser;
48: PetscCall(PetscInitialize(&argc, &argv, NULL, help));
49: PetscCall(TSCreate(PETSC_COMM_WORLD, &ts));
50: PetscCall(TSSetProblemType(ts, TS_NONLINEAR));
51: PetscCall(TSSetType(ts, TSEULER));
52: PetscCall(TSSetFromOptions(ts));
53: PetscCall(VecCreateMPI(PETSC_COMM_WORLD, PETSC_DECIDE, 1, &tsrhs));
54: PetscCall(VecCreateMPI(PETSC_COMM_WORLD, PETSC_DECIDE, 1, &U));
55: PetscCall(TSSetRHSFunction(ts, tsrhs, TSFunction, &ctx));
56: PetscCall(TSSetMaxTime(ts, 1.0));
57: ctx.f = f;
59: PetscCall(SNESCreate(PETSC_COMM_WORLD, &ctx.snes));
60: PetscCall(SNESSetFromOptions(ctx.snes));
61: PetscCall(SNESSetFunction(ctx.snes, NULL, SNESFunction, &ctx));
62: PetscCall(SNESSetJacobian(ctx.snes, NULL, NULL, SNESComputeJacobianDefault, &ctx));
63: ctx.F = F;
64: PetscCall(VecCreateMPI(PETSC_COMM_WORLD, PETSC_DECIDE, 1, &ctx.V));
66: PetscCall(VecSet(U, 1.0));
67: PetscCall(TSSolve(ts, U));
69: PetscCall(VecDestroy(&ctx.V));
70: PetscCall(VecDestroy(&tsrhs));
71: PetscCall(VecDestroy(&U));
72: PetscCall(SNESDestroy(&ctx.snes));
73: PetscCall(TSDestroy(&ts));
74: PetscCall(PetscFinalize());
75: return 0;
76: }
78: /*
79: Defines the RHS function that is passed to the time-integrator.
81: Solves F(U,V) for V and then computes f(U,V)
82: */
83: PetscErrorCode TSFunction(TS ts, PetscReal t, Vec U, Vec F, void *actx)
84: {
85: AppCtx *ctx = (AppCtx *)actx;
87: PetscFunctionBeginUser;
88: ctx->t = t;
89: ctx->U = U;
90: PetscCall(SNESSolve(ctx->snes, NULL, ctx->V));
91: PetscCall((*ctx->f)(t, U, ctx->V, F));
92: PetscFunctionReturn(PETSC_SUCCESS);
93: }
95: /*
96: Defines the nonlinear function that is passed to the nonlinear solver
97: */
98: PetscErrorCode SNESFunction(SNES snes, Vec V, Vec F, void *actx)
99: {
100: AppCtx *ctx = (AppCtx *)actx;
102: PetscFunctionBeginUser;
103: PetscCall((*ctx->F)(ctx->t, ctx->U, V, F));
104: PetscFunctionReturn(PETSC_SUCCESS);
105: }
107: /*TEST
109: test:
110: args: -ts_monitor -ts_view
112: TEST*/