static char help[] = "Small ODE to test TS accuracy.\n"; /* The ODE u1_t = cos(t), u2_t = sin(u2) with analytical solution u1(t) = sin(t), u2(t) = 2 * atan(exp(t) * tan(0.5)) is used to test the accuracy of TS schemes. */ #include /* Defines the ODE passed to the ODE solver in explicit form: U_t = F(U) */ static PetscErrorCode RHSFunction(TS ts, PetscReal t, Vec U, Vec F, void *s) { PetscErrorCode ierr; PetscScalar *f; const PetscScalar *u; PetscFunctionBegin; ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); ierr = VecGetArray(F,&f);CHKERRQ(ierr); f[0] = PetscCosReal(t); f[1] = PetscSinReal(u[1]); ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); ierr = VecRestoreArray(F,&f);CHKERRQ(ierr); PetscFunctionReturn(0); } /* Defines the exact solution. */ static PetscErrorCode ExactSolution(PetscReal t, Vec U) { PetscErrorCode ierr; PetscScalar *u; PetscFunctionBegin; ierr = VecGetArray(U,&u);CHKERRQ(ierr); u[0] = PetscSinReal(t); u[1] = 2 * PetscAtanReal(PetscExpReal(t) * PetscTanReal(0.5)); ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); PetscFunctionReturn(0); } int main(int argc,char **argv) { TS ts; /* ODE integrator */ Vec U; /* numerical solution will be stored here */ Vec Uex; /* analytical (exact) solution will be stored here */ PetscErrorCode ierr; PetscMPIInt size; PetscInt n = 2; PetscScalar *u; PetscReal t, final_time = 1.0, dt = 0.25; PetscReal error; TSAdapt adapt; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRMPI(ierr); if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Only for sequential runs"); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSROSW);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set ODE routines - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,RHSFunction,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecCreate(PETSC_COMM_WORLD,&U);CHKERRQ(ierr); ierr = VecSetSizes(U,n,PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetUp(U);CHKERRQ(ierr); ierr = VecGetArray(U,&u);CHKERRQ(ierr); u[0] = 0.0; u[1] = 1.0; ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); ierr = TSSetSolution(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set solver options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); ierr = TSSetMaxTime(ts,final_time);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetTimeStep(ts,dt);CHKERRQ(ierr); /* The adapative time step controller is forced to take constant time steps. */ ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); ierr = TSAdaptSetType(adapt,TSADAPTNONE);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Run timestepping solver and compute error - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,U);CHKERRQ(ierr); ierr = TSGetTime(ts,&t);CHKERRQ(ierr); if (PetscAbsReal(t-final_time)>100*PETSC_MACHINE_EPSILON) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Note: There is a difference of %g between the prescribed final time %g and the actual final time.\n",(double)(final_time-t),(double)final_time);CHKERRQ(ierr); } ierr = VecDuplicate(U,&Uex);CHKERRQ(ierr); ierr = ExactSolution(t,Uex);CHKERRQ(ierr); ierr = VecAYPX(Uex,-1.0,U);CHKERRQ(ierr); ierr = VecNorm(Uex,NORM_2,&error);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error at final time: %.2E\n",(double)error);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = VecDestroy(&Uex);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; } /*TEST test: suffix: 3bs args: -ts_type rk -ts_rk_type 3bs requires: !single test: suffix: 5bs args: -ts_type rk -ts_rk_type 5bs requires: !single test: suffix: 5dp args: -ts_type rk -ts_rk_type 5dp requires: !single test: suffix: 6vr args: -ts_type rk -ts_rk_type 6vr requires: !single test: suffix: 7vr args: -ts_type rk -ts_rk_type 7vr requires: !single test: suffix: 8vr args: -ts_type rk -ts_rk_type 8vr requires: !single TEST*/