xref: /petsc/src/ts/event/tests/ex16.c (revision fa9584fb611836aca54f08ab8720e6338ac4bd38)
1*fa9584fbSIlya Fursov static char help[] = "Solves the trivial ODE du/dt = 1, u(0) = 0. \n\n";
2*fa9584fbSIlya Fursov /*
3*fa9584fbSIlya Fursov   This example tests TSEvent's capability to handle complicated cases.
4*fa9584fbSIlya Fursov   Test 1: an event close to endpoint of a time step should not be detected twice.
5*fa9584fbSIlya Fursov   Test 2: two events in the same time step should be detected in the correct order.
6*fa9584fbSIlya Fursov   Test 3: three events in the same time step should be detected in the correct order.
7*fa9584fbSIlya Fursov */
8*fa9584fbSIlya Fursov 
9*fa9584fbSIlya Fursov #include <petscts.h>
10*fa9584fbSIlya Fursov 
11*fa9584fbSIlya Fursov static PetscErrorCode RHSFunction(TS, PetscReal, Vec, Vec, void *);
12*fa9584fbSIlya Fursov static PetscErrorCode RHSJacobian(TS, PetscReal, Vec, Mat, Mat, void *);
13*fa9584fbSIlya Fursov 
14*fa9584fbSIlya Fursov static PetscErrorCode Event(TS, PetscReal, Vec, PetscReal *, void *);
15*fa9584fbSIlya Fursov static PetscErrorCode PostEvent(TS, PetscInt, PetscInt[], PetscReal, Vec, PetscBool, void *);
16*fa9584fbSIlya Fursov 
17*fa9584fbSIlya Fursov int main(int argc, char **argv)
18*fa9584fbSIlya Fursov {
19*fa9584fbSIlya Fursov   TS              ts;
20*fa9584fbSIlya Fursov   const PetscReal t_end = 2.0;
21*fa9584fbSIlya Fursov   Vec             x;
22*fa9584fbSIlya Fursov   Vec             f;
23*fa9584fbSIlya Fursov   Mat             A;
24*fa9584fbSIlya Fursov 
25*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
26*fa9584fbSIlya Fursov   PetscCall(PetscInitialize(&argc, &argv, (char *)0, help));
27*fa9584fbSIlya Fursov 
28*fa9584fbSIlya Fursov   PetscCall(TSCreate(PETSC_COMM_WORLD, &ts));
29*fa9584fbSIlya Fursov 
30*fa9584fbSIlya Fursov   PetscCall(VecCreate(PETSC_COMM_WORLD, &f));
31*fa9584fbSIlya Fursov   PetscCall(VecSetSizes(f, 1, PETSC_DECIDE));
32*fa9584fbSIlya Fursov   PetscCall(VecSetFromOptions(f));
33*fa9584fbSIlya Fursov   PetscCall(VecSetUp(f));
34*fa9584fbSIlya Fursov   PetscCall(TSSetRHSFunction(ts, f, RHSFunction, NULL));
35*fa9584fbSIlya Fursov   PetscCall(VecDestroy(&f));
36*fa9584fbSIlya Fursov 
37*fa9584fbSIlya Fursov   PetscCall(MatCreate(PETSC_COMM_WORLD, &A));
38*fa9584fbSIlya Fursov   PetscCall(MatSetSizes(A, 1, 1, PETSC_DECIDE, PETSC_DECIDE));
39*fa9584fbSIlya Fursov   PetscCall(MatSetFromOptions(A));
40*fa9584fbSIlya Fursov   PetscCall(MatSetUp(A));
41*fa9584fbSIlya Fursov   PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
42*fa9584fbSIlya Fursov   PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
43*fa9584fbSIlya Fursov   /* ensure that the Jacobian matrix has diagonal entries since that is required by TS */
44*fa9584fbSIlya Fursov   PetscCall(MatShift(A, (PetscReal)1));
45*fa9584fbSIlya Fursov   PetscCall(MatShift(A, (PetscReal)-1));
46*fa9584fbSIlya Fursov   PetscCall(TSSetRHSJacobian(ts, A, A, RHSJacobian, NULL));
47*fa9584fbSIlya Fursov   PetscCall(MatDestroy(&A));
48*fa9584fbSIlya Fursov 
49*fa9584fbSIlya Fursov   PetscCall(VecCreate(PETSC_COMM_WORLD, &x));
50*fa9584fbSIlya Fursov   PetscCall(VecSetSizes(x, 1, PETSC_DECIDE));
51*fa9584fbSIlya Fursov   PetscCall(VecSetFromOptions(x));
52*fa9584fbSIlya Fursov   PetscCall(VecSetUp(x));
53*fa9584fbSIlya Fursov   PetscCall(TSSetSolution(ts, x));
54*fa9584fbSIlya Fursov   PetscCall(VecDestroy(&x));
55*fa9584fbSIlya Fursov 
56*fa9584fbSIlya Fursov   {
57*fa9584fbSIlya Fursov     PetscInt  direction[3];
58*fa9584fbSIlya Fursov     PetscBool terminate[3];
59*fa9584fbSIlya Fursov     direction[0] = +1;
60*fa9584fbSIlya Fursov     terminate[0] = PETSC_FALSE;
61*fa9584fbSIlya Fursov     direction[1] = -1;
62*fa9584fbSIlya Fursov     terminate[1] = PETSC_FALSE;
63*fa9584fbSIlya Fursov     direction[2] = 0;
64*fa9584fbSIlya Fursov     terminate[2] = PETSC_FALSE;
65*fa9584fbSIlya Fursov     PetscCall(TSSetEventHandler(ts, 3, direction, terminate, Event, PostEvent, NULL));
66*fa9584fbSIlya Fursov   }
67*fa9584fbSIlya Fursov   PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER));
68*fa9584fbSIlya Fursov   PetscCall(TSSetMaxTime(ts, t_end));
69*fa9584fbSIlya Fursov   PetscCall(TSSetFromOptions(ts));
70*fa9584fbSIlya Fursov 
71*fa9584fbSIlya Fursov   PetscCall(TSSolve(ts, NULL));
72*fa9584fbSIlya Fursov 
73*fa9584fbSIlya Fursov   PetscCall(TSDestroy(&ts));
74*fa9584fbSIlya Fursov   PetscCall(PetscFinalize());
75*fa9584fbSIlya Fursov   return 0;
76*fa9584fbSIlya Fursov }
77*fa9584fbSIlya Fursov 
78*fa9584fbSIlya Fursov PetscErrorCode RHSFunction(TS ts, PetscReal t, Vec x, Vec f, void *ctx)
79*fa9584fbSIlya Fursov {
80*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
81*fa9584fbSIlya Fursov   PetscCall(VecSet(f, (PetscReal)1));
82*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
83*fa9584fbSIlya Fursov }
84*fa9584fbSIlya Fursov 
85*fa9584fbSIlya Fursov PetscErrorCode RHSJacobian(TS ts, PetscReal t, Vec x, Mat A, Mat B, void *ctx)
86*fa9584fbSIlya Fursov {
87*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
88*fa9584fbSIlya Fursov   PetscCall(MatZeroEntries(B));
89*fa9584fbSIlya Fursov   if (B != A) PetscCall(MatZeroEntries(A));
90*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
91*fa9584fbSIlya Fursov }
92*fa9584fbSIlya Fursov 
93*fa9584fbSIlya Fursov PetscErrorCode Event(TS ts, PetscReal t, Vec x, PetscReal *fvalue, void *ctx)
94*fa9584fbSIlya Fursov {
95*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
96*fa9584fbSIlya Fursov   fvalue[0] = t - 1.1;
97*fa9584fbSIlya Fursov   fvalue[1] = 1.2 - t;
98*fa9584fbSIlya Fursov   fvalue[2] = t - 1.3;
99*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
100*fa9584fbSIlya Fursov }
101*fa9584fbSIlya Fursov 
102*fa9584fbSIlya Fursov PetscErrorCode PostEvent(TS ts, PetscInt nevents, PetscInt event_list[], PetscReal t, Vec x, PetscBool forwardsolve, void *ctx)
103*fa9584fbSIlya Fursov {
104*fa9584fbSIlya Fursov   PetscInt           i;
105*fa9584fbSIlya Fursov   const PetscScalar *a;
106*fa9584fbSIlya Fursov 
107*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
108*fa9584fbSIlya Fursov   PetscCall(TSGetStepNumber(ts, &i));
109*fa9584fbSIlya Fursov   PetscCall(VecGetArrayRead(x, &a));
110*fa9584fbSIlya Fursov   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%-10s-> step %" PetscInt_FMT " time %g value %g\n", PETSC_FUNCTION_NAME, i, (double)t, (double)PetscRealPart(a[0])));
111*fa9584fbSIlya Fursov   PetscCall(VecRestoreArrayRead(x, &a));
112*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
113*fa9584fbSIlya Fursov }
114*fa9584fbSIlya Fursov 
115*fa9584fbSIlya Fursov /*TEST
116*fa9584fbSIlya Fursov 
117*fa9584fbSIlya Fursov     test:
118*fa9584fbSIlya Fursov       args: -ts_type beuler -ts_dt 0.1 -ts_event_monitor
119*fa9584fbSIlya Fursov 
120*fa9584fbSIlya Fursov     test:
121*fa9584fbSIlya Fursov       suffix: 2
122*fa9584fbSIlya Fursov       args: -ts_type beuler -ts_dt 0.2 -ts_event_monitor
123*fa9584fbSIlya Fursov 
124*fa9584fbSIlya Fursov     test:
125*fa9584fbSIlya Fursov       suffix: 3
126*fa9584fbSIlya Fursov       args: -ts_type beuler -ts_dt 0.5 -ts_event_monitor -ts_event_post_event_step 0
127*fa9584fbSIlya Fursov TEST*/
128