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