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