1*fa9584fbSIlya Fursov static char help[] = "Solves the trivial ODE du/dt = 1, u(0) = 0. \n\n"; 2*fa9584fbSIlya Fursov 3*fa9584fbSIlya Fursov #include <petscts.h> 4*fa9584fbSIlya Fursov #include <petscpc.h> 5*fa9584fbSIlya Fursov 6*fa9584fbSIlya Fursov static PetscErrorCode RHSFunction(TS, PetscReal, Vec, Vec, void *); 7*fa9584fbSIlya Fursov static PetscErrorCode RHSJacobian(TS, PetscReal, Vec, Mat, Mat, void *); 8*fa9584fbSIlya Fursov 9*fa9584fbSIlya Fursov static PetscErrorCode PreStep(TS); 10*fa9584fbSIlya Fursov static PetscErrorCode PostStep(TS); 11*fa9584fbSIlya Fursov static PetscErrorCode Monitor(TS, PetscInt, PetscReal, Vec, void *); 12*fa9584fbSIlya Fursov static PetscErrorCode Event(TS, PetscReal, Vec, PetscReal *, void *); 13*fa9584fbSIlya Fursov static PetscErrorCode PostEvent(TS, PetscInt, PetscInt[], PetscReal, Vec, PetscBool, void *); 14*fa9584fbSIlya Fursov static PetscErrorCode TransferSetUp(TS, PetscInt, PetscReal, Vec, PetscBool *, void *); 15*fa9584fbSIlya Fursov static PetscErrorCode Transfer(TS, PetscInt, Vec[], Vec[], void *); 16*fa9584fbSIlya Fursov 17*fa9584fbSIlya Fursov int main(int argc, char **argv) 18*fa9584fbSIlya Fursov { 19*fa9584fbSIlya Fursov TS ts; 20*fa9584fbSIlya Fursov PetscInt n, ntransfer = 2; 21*fa9584fbSIlya Fursov const PetscInt n_end = 11; 22*fa9584fbSIlya Fursov PetscReal t; 23*fa9584fbSIlya Fursov const PetscReal t_end = 11; 24*fa9584fbSIlya Fursov Vec x; 25*fa9584fbSIlya Fursov Vec f; 26*fa9584fbSIlya Fursov Mat A; 27*fa9584fbSIlya Fursov 28*fa9584fbSIlya Fursov PetscFunctionBeginUser; 29*fa9584fbSIlya Fursov PetscCall(PetscInitialize(&argc, &argv, (char *)0, help)); 30*fa9584fbSIlya Fursov 31*fa9584fbSIlya Fursov PetscCall(TSCreate(PETSC_COMM_WORLD, &ts)); 32*fa9584fbSIlya Fursov 33*fa9584fbSIlya Fursov PetscCall(VecCreate(PETSC_COMM_WORLD, &f)); 34*fa9584fbSIlya Fursov PetscCall(VecSetSizes(f, 1, PETSC_DECIDE)); 35*fa9584fbSIlya Fursov PetscCall(VecSetFromOptions(f)); 36*fa9584fbSIlya Fursov PetscCall(VecSetUp(f)); 37*fa9584fbSIlya Fursov PetscCall(TSSetRHSFunction(ts, f, RHSFunction, NULL)); 38*fa9584fbSIlya Fursov PetscCall(VecDestroy(&f)); 39*fa9584fbSIlya Fursov 40*fa9584fbSIlya Fursov PetscCall(MatCreate(PETSC_COMM_WORLD, &A)); 41*fa9584fbSIlya Fursov PetscCall(MatSetSizes(A, 1, 1, PETSC_DECIDE, PETSC_DECIDE)); 42*fa9584fbSIlya Fursov PetscCall(MatSetFromOptions(A)); 43*fa9584fbSIlya Fursov PetscCall(MatSetUp(A)); 44*fa9584fbSIlya Fursov PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 45*fa9584fbSIlya Fursov PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 46*fa9584fbSIlya Fursov /* ensure that the Jacobian matrix has diagonal entries since that is required by TS */ 47*fa9584fbSIlya Fursov PetscCall(MatShift(A, (PetscReal)1)); 48*fa9584fbSIlya Fursov PetscCall(MatShift(A, (PetscReal)-1)); 49*fa9584fbSIlya Fursov PetscCall(TSSetRHSJacobian(ts, A, A, RHSJacobian, NULL)); 50*fa9584fbSIlya Fursov PetscCall(MatDestroy(&A)); 51*fa9584fbSIlya Fursov 52*fa9584fbSIlya Fursov PetscCall(VecCreate(PETSC_COMM_WORLD, &x)); 53*fa9584fbSIlya Fursov PetscCall(VecSetSizes(x, 1, PETSC_DECIDE)); 54*fa9584fbSIlya Fursov PetscCall(VecSetFromOptions(x)); 55*fa9584fbSIlya Fursov PetscCall(VecSetUp(x)); 56*fa9584fbSIlya Fursov PetscCall(TSSetSolution(ts, x)); 57*fa9584fbSIlya Fursov PetscCall(VecDestroy(&x)); 58*fa9584fbSIlya Fursov 59*fa9584fbSIlya Fursov PetscCall(TSMonitorSet(ts, Monitor, NULL, NULL)); 60*fa9584fbSIlya Fursov PetscCall(TSSetPreStep(ts, PreStep)); 61*fa9584fbSIlya Fursov PetscCall(TSSetPostStep(ts, PostStep)); 62*fa9584fbSIlya Fursov 63*fa9584fbSIlya Fursov { 64*fa9584fbSIlya Fursov TSAdapt adapt; 65*fa9584fbSIlya Fursov PetscCall(TSGetAdapt(ts, &adapt)); 66*fa9584fbSIlya Fursov PetscCall(TSAdaptSetType(adapt, TSADAPTNONE)); 67*fa9584fbSIlya Fursov } 68*fa9584fbSIlya Fursov { 69*fa9584fbSIlya Fursov PetscInt direction[3]; 70*fa9584fbSIlya Fursov PetscBool terminate[3]; 71*fa9584fbSIlya Fursov direction[0] = +1; 72*fa9584fbSIlya Fursov terminate[0] = PETSC_FALSE; 73*fa9584fbSIlya Fursov direction[1] = -1; 74*fa9584fbSIlya Fursov terminate[1] = PETSC_FALSE; 75*fa9584fbSIlya Fursov direction[2] = 0; 76*fa9584fbSIlya Fursov terminate[2] = PETSC_FALSE; 77*fa9584fbSIlya Fursov PetscCall(TSSetTimeStep(ts, 1)); 78*fa9584fbSIlya Fursov PetscCall(TSSetEventHandler(ts, 3, direction, terminate, Event, PostEvent, NULL)); 79*fa9584fbSIlya Fursov } 80*fa9584fbSIlya Fursov PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER)); 81*fa9584fbSIlya Fursov PetscCall(TSSetResize(ts, TransferSetUp, Transfer, &ntransfer)); 82*fa9584fbSIlya Fursov PetscCall(TSSetFromOptions(ts)); 83*fa9584fbSIlya Fursov 84*fa9584fbSIlya Fursov /* --- First Solve --- */ 85*fa9584fbSIlya Fursov 86*fa9584fbSIlya Fursov PetscCall(TSSetStepNumber(ts, 0)); 87*fa9584fbSIlya Fursov PetscCall(TSSetTimeStep(ts, 1)); 88*fa9584fbSIlya Fursov PetscCall(TSSetTime(ts, 0)); 89*fa9584fbSIlya Fursov PetscCall(TSSetMaxTime(ts, PETSC_MAX_REAL)); 90*fa9584fbSIlya Fursov PetscCall(TSSetMaxSteps(ts, 3)); 91*fa9584fbSIlya Fursov 92*fa9584fbSIlya Fursov PetscCall(TSGetTime(ts, &t)); 93*fa9584fbSIlya Fursov PetscCall(TSGetSolution(ts, &x)); 94*fa9584fbSIlya Fursov PetscCall(VecSet(x, t)); 95*fa9584fbSIlya Fursov while (t < t_end) { 96*fa9584fbSIlya Fursov PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: Begin\n")); 97*fa9584fbSIlya Fursov PetscCall(TSSolve(ts, NULL)); 98*fa9584fbSIlya Fursov PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: End\n\n")); 99*fa9584fbSIlya Fursov PetscCall(TSGetTime(ts, &t)); 100*fa9584fbSIlya Fursov PetscCall(TSGetStepNumber(ts, &n)); 101*fa9584fbSIlya Fursov PetscCall(TSSetMaxSteps(ts, PetscMin(n + 3, n_end))); 102*fa9584fbSIlya Fursov } 103*fa9584fbSIlya Fursov PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: Begin\n")); 104*fa9584fbSIlya Fursov PetscCall(TSSolve(ts, NULL)); 105*fa9584fbSIlya Fursov PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: End\n\n")); 106*fa9584fbSIlya Fursov 107*fa9584fbSIlya Fursov /* --- Second Solve --- */ 108*fa9584fbSIlya Fursov 109*fa9584fbSIlya Fursov PetscCall(TSSetStepNumber(ts, 0)); 110*fa9584fbSIlya Fursov PetscCall(TSSetTimeStep(ts, 1)); 111*fa9584fbSIlya Fursov PetscCall(TSSetTime(ts, 0)); 112*fa9584fbSIlya Fursov PetscCall(TSSetMaxTime(ts, 3)); 113*fa9584fbSIlya Fursov PetscCall(TSSetMaxSteps(ts, PETSC_MAX_INT)); 114*fa9584fbSIlya Fursov 115*fa9584fbSIlya Fursov PetscCall(TSGetTime(ts, &t)); 116*fa9584fbSIlya Fursov PetscCall(TSGetSolution(ts, &x)); 117*fa9584fbSIlya Fursov PetscCall(VecSet(x, t)); 118*fa9584fbSIlya Fursov while (t < t_end) { 119*fa9584fbSIlya Fursov PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: Begin\n")); 120*fa9584fbSIlya Fursov PetscCall(TSSolve(ts, NULL)); 121*fa9584fbSIlya Fursov PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: End\n\n")); 122*fa9584fbSIlya Fursov PetscCall(TSGetTime(ts, &t)); 123*fa9584fbSIlya Fursov PetscCall(TSSetMaxTime(ts, PetscMin(t + 3, t_end))); 124*fa9584fbSIlya Fursov } 125*fa9584fbSIlya Fursov PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: Begin\n")); 126*fa9584fbSIlya Fursov PetscCall(TSSolve(ts, NULL)); 127*fa9584fbSIlya Fursov PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: End\n\n")); 128*fa9584fbSIlya Fursov 129*fa9584fbSIlya Fursov /* --- */ 130*fa9584fbSIlya Fursov 131*fa9584fbSIlya Fursov PetscCall(TSDestroy(&ts)); 132*fa9584fbSIlya Fursov 133*fa9584fbSIlya Fursov PetscCall(PetscFinalize()); 134*fa9584fbSIlya Fursov return 0; 135*fa9584fbSIlya Fursov } 136*fa9584fbSIlya Fursov 137*fa9584fbSIlya Fursov /* -------------------------------------------------------------------*/ 138*fa9584fbSIlya Fursov 139*fa9584fbSIlya Fursov PetscErrorCode RHSFunction(TS ts, PetscReal t, Vec x, Vec f, void *ctx) 140*fa9584fbSIlya Fursov { 141*fa9584fbSIlya Fursov PetscFunctionBeginUser; 142*fa9584fbSIlya Fursov PetscCall(VecSet(f, (PetscReal)1)); 143*fa9584fbSIlya Fursov PetscFunctionReturn(PETSC_SUCCESS); 144*fa9584fbSIlya Fursov } 145*fa9584fbSIlya Fursov 146*fa9584fbSIlya Fursov PetscErrorCode RHSJacobian(TS ts, PetscReal t, Vec x, Mat A, Mat B, void *ctx) 147*fa9584fbSIlya Fursov { 148*fa9584fbSIlya Fursov PetscFunctionBeginUser; 149*fa9584fbSIlya Fursov PetscCall(MatZeroEntries(B)); 150*fa9584fbSIlya Fursov if (B != A) PetscCall(MatZeroEntries(A)); 151*fa9584fbSIlya Fursov PetscFunctionReturn(PETSC_SUCCESS); 152*fa9584fbSIlya Fursov } 153*fa9584fbSIlya Fursov 154*fa9584fbSIlya Fursov PetscErrorCode PreStep(TS ts) 155*fa9584fbSIlya Fursov { 156*fa9584fbSIlya Fursov PetscInt n; 157*fa9584fbSIlya Fursov PetscReal t; 158*fa9584fbSIlya Fursov Vec x; 159*fa9584fbSIlya Fursov const PetscScalar *a; 160*fa9584fbSIlya Fursov 161*fa9584fbSIlya Fursov PetscFunctionBeginUser; 162*fa9584fbSIlya Fursov PetscCall(TSGetStepNumber(ts, &n)); 163*fa9584fbSIlya Fursov PetscCall(TSGetTime(ts, &t)); 164*fa9584fbSIlya Fursov PetscCall(TSGetSolution(ts, &x)); 165*fa9584fbSIlya Fursov PetscCall(VecGetArrayRead(x, &a)); 166*fa9584fbSIlya Fursov PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%-10s-> step %" PetscInt_FMT " time %g value %g\n", PETSC_FUNCTION_NAME, n, (double)t, (double)PetscRealPart(a[0]))); 167*fa9584fbSIlya Fursov PetscCall(VecRestoreArrayRead(x, &a)); 168*fa9584fbSIlya Fursov PetscFunctionReturn(PETSC_SUCCESS); 169*fa9584fbSIlya Fursov } 170*fa9584fbSIlya Fursov 171*fa9584fbSIlya Fursov PetscErrorCode PostStep(TS ts) 172*fa9584fbSIlya Fursov { 173*fa9584fbSIlya Fursov PetscInt n; 174*fa9584fbSIlya Fursov PetscReal t; 175*fa9584fbSIlya Fursov Vec x; 176*fa9584fbSIlya Fursov const PetscScalar *a; 177*fa9584fbSIlya Fursov 178*fa9584fbSIlya Fursov PetscFunctionBeginUser; 179*fa9584fbSIlya Fursov PetscCall(TSGetStepNumber(ts, &n)); 180*fa9584fbSIlya Fursov PetscCall(TSGetTime(ts, &t)); 181*fa9584fbSIlya Fursov PetscCall(TSGetSolution(ts, &x)); 182*fa9584fbSIlya Fursov PetscCall(VecGetArrayRead(x, &a)); 183*fa9584fbSIlya Fursov PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%-10s-> step %" PetscInt_FMT " time %g value %g\n", PETSC_FUNCTION_NAME, n, (double)t, (double)PetscRealPart(a[0]))); 184*fa9584fbSIlya Fursov PetscCall(VecRestoreArrayRead(x, &a)); 185*fa9584fbSIlya Fursov PetscFunctionReturn(PETSC_SUCCESS); 186*fa9584fbSIlya Fursov } 187*fa9584fbSIlya Fursov 188*fa9584fbSIlya Fursov PetscErrorCode Monitor(TS ts, PetscInt n, PetscReal t, Vec x, void *ctx) 189*fa9584fbSIlya Fursov { 190*fa9584fbSIlya Fursov const PetscScalar *a; 191*fa9584fbSIlya Fursov 192*fa9584fbSIlya Fursov PetscFunctionBeginUser; 193*fa9584fbSIlya Fursov PetscCall(VecGetArrayRead(x, &a)); 194*fa9584fbSIlya Fursov PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%-10s-> step %" PetscInt_FMT " time %g value %g\n", PETSC_FUNCTION_NAME, n, (double)t, (double)PetscRealPart(a[0]))); 195*fa9584fbSIlya Fursov PetscCall(VecRestoreArrayRead(x, &a)); 196*fa9584fbSIlya Fursov PetscFunctionReturn(PETSC_SUCCESS); 197*fa9584fbSIlya Fursov } 198*fa9584fbSIlya Fursov 199*fa9584fbSIlya Fursov PetscErrorCode Event(TS ts, PetscReal t, Vec x, PetscReal *fvalue, void *ctx) 200*fa9584fbSIlya Fursov { 201*fa9584fbSIlya Fursov PetscFunctionBeginUser; 202*fa9584fbSIlya Fursov fvalue[0] = t - 5; 203*fa9584fbSIlya Fursov fvalue[1] = 7 - t; 204*fa9584fbSIlya Fursov fvalue[2] = t - 9; 205*fa9584fbSIlya Fursov PetscFunctionReturn(PETSC_SUCCESS); 206*fa9584fbSIlya Fursov } 207*fa9584fbSIlya Fursov 208*fa9584fbSIlya Fursov PetscErrorCode PostEvent(TS ts, PetscInt nevents, PetscInt event_list[], PetscReal t, Vec x, PetscBool forwardsolve, void *ctx) 209*fa9584fbSIlya Fursov { 210*fa9584fbSIlya Fursov PetscInt i; 211*fa9584fbSIlya Fursov const PetscScalar *a; 212*fa9584fbSIlya Fursov 213*fa9584fbSIlya Fursov PetscFunctionBeginUser; 214*fa9584fbSIlya Fursov PetscCall(TSGetStepNumber(ts, &i)); 215*fa9584fbSIlya Fursov PetscCall(VecGetArrayRead(x, &a)); 216*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]))); 217*fa9584fbSIlya Fursov PetscCall(VecRestoreArrayRead(x, &a)); 218*fa9584fbSIlya Fursov PetscFunctionReturn(PETSC_SUCCESS); 219*fa9584fbSIlya Fursov } 220*fa9584fbSIlya Fursov 221*fa9584fbSIlya Fursov PetscErrorCode TransferSetUp(TS ts, PetscInt n, PetscReal t, Vec x, PetscBool *flg, void *ctx) 222*fa9584fbSIlya Fursov { 223*fa9584fbSIlya Fursov PetscInt *nt = (PetscInt *)ctx; 224*fa9584fbSIlya Fursov 225*fa9584fbSIlya Fursov PetscFunctionBeginUser; 226*fa9584fbSIlya Fursov *flg = (PetscBool)(*nt && n && n % (*nt) == 0); 227*fa9584fbSIlya Fursov PetscFunctionReturn(PETSC_SUCCESS); 228*fa9584fbSIlya Fursov } 229*fa9584fbSIlya Fursov 230*fa9584fbSIlya Fursov PetscErrorCode Transfer(TS ts, PetscInt nv, Vec vin[], Vec vout[], void *ctx) 231*fa9584fbSIlya Fursov { 232*fa9584fbSIlya Fursov PetscInt i; 233*fa9584fbSIlya Fursov 234*fa9584fbSIlya Fursov PetscFunctionBeginUser; 235*fa9584fbSIlya Fursov PetscCall(TSGetStepNumber(ts, &i)); 236*fa9584fbSIlya Fursov PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%-10s-> step %" PetscInt_FMT " nv %" PetscInt_FMT "\n", PETSC_FUNCTION_NAME, i, nv)); 237*fa9584fbSIlya Fursov for (i = 0; i < nv; i++) { 238*fa9584fbSIlya Fursov PetscCall(VecDuplicate(vin[i], &vout[i])); 239*fa9584fbSIlya Fursov PetscCall(VecCopy(vin[i], vout[i])); 240*fa9584fbSIlya Fursov } 241*fa9584fbSIlya Fursov PetscFunctionReturn(PETSC_SUCCESS); 242*fa9584fbSIlya Fursov } 243*fa9584fbSIlya Fursov 244*fa9584fbSIlya Fursov /*TEST 245*fa9584fbSIlya Fursov 246*fa9584fbSIlya Fursov test: 247*fa9584fbSIlya Fursov suffix: euler 248*fa9584fbSIlya Fursov diff_args: -j 249*fa9584fbSIlya Fursov args: -ts_type euler 250*fa9584fbSIlya Fursov output_file: output/ex1.out 251*fa9584fbSIlya Fursov 252*fa9584fbSIlya Fursov test: 253*fa9584fbSIlya Fursov suffix: ssp 254*fa9584fbSIlya Fursov diff_args: -j 255*fa9584fbSIlya Fursov args: -ts_type ssp 256*fa9584fbSIlya Fursov output_file: output/ex1.out 257*fa9584fbSIlya Fursov 258*fa9584fbSIlya Fursov test: 259*fa9584fbSIlya Fursov suffix: rk 260*fa9584fbSIlya Fursov diff_args: -j 261*fa9584fbSIlya Fursov args: -ts_type rk 262*fa9584fbSIlya Fursov output_file: output/ex1.out 263*fa9584fbSIlya Fursov 264*fa9584fbSIlya Fursov test: 265*fa9584fbSIlya Fursov suffix: beuler 266*fa9584fbSIlya Fursov diff_args: -j 267*fa9584fbSIlya Fursov args: -ts_type beuler 268*fa9584fbSIlya Fursov output_file: output/ex1.out 269*fa9584fbSIlya Fursov 270*fa9584fbSIlya Fursov test: 271*fa9584fbSIlya Fursov suffix: cn 272*fa9584fbSIlya Fursov diff_args: -j 273*fa9584fbSIlya Fursov args: -ts_type cn 274*fa9584fbSIlya Fursov output_file: output/ex1.out 275*fa9584fbSIlya Fursov 276*fa9584fbSIlya Fursov test: 277*fa9584fbSIlya Fursov suffix: theta 278*fa9584fbSIlya Fursov args: -ts_type theta 279*fa9584fbSIlya Fursov diff_args: -j 280*fa9584fbSIlya Fursov output_file: output/ex1.out 281*fa9584fbSIlya Fursov 282*fa9584fbSIlya Fursov test: 283*fa9584fbSIlya Fursov suffix: bdf 284*fa9584fbSIlya Fursov diff_args: -j 285*fa9584fbSIlya Fursov args: -ts_type bdf 286*fa9584fbSIlya Fursov output_file: output/ex1_bdf.out 287*fa9584fbSIlya Fursov 288*fa9584fbSIlya Fursov test: 289*fa9584fbSIlya Fursov suffix: alpha 290*fa9584fbSIlya Fursov diff_args: -j 291*fa9584fbSIlya Fursov args: -ts_type alpha 292*fa9584fbSIlya Fursov output_file: output/ex1.out 293*fa9584fbSIlya Fursov 294*fa9584fbSIlya Fursov test: 295*fa9584fbSIlya Fursov suffix: rosw 296*fa9584fbSIlya Fursov diff_args: -j 297*fa9584fbSIlya Fursov args: -ts_type rosw 298*fa9584fbSIlya Fursov output_file: output/ex1.out 299*fa9584fbSIlya Fursov 300*fa9584fbSIlya Fursov test: 301*fa9584fbSIlya Fursov suffix: arkimex 302*fa9584fbSIlya Fursov diff_args: -j 303*fa9584fbSIlya Fursov args: -ts_type arkimex 304*fa9584fbSIlya Fursov output_file: output/ex1.out 305*fa9584fbSIlya Fursov 306*fa9584fbSIlya Fursov TEST*/ 307