/* Formatted test for TS routines. Solves U_t=F(t,u) Where: [2*u1+u2 F(t,u)= [u1+2*u2+u3 [ u2+2*u3 We can compare the solutions from euler, beuler and SUNDIALS to see what is the difference. */ static char help[] = "Solves a linear ODE. \n\n"; #include #include extern PetscErrorCode RHSFunction(TS,PetscReal,Vec,Vec,void*); extern PetscErrorCode RHSJacobian(TS,PetscReal,Vec,Mat,Mat,void*); extern PetscErrorCode Monitor(TS,PetscInt,PetscReal,Vec,void*); extern PetscErrorCode Initial(Vec,void*); extern PetscErrorCode MyMatMult(Mat,Vec,Vec); extern PetscReal solx(PetscReal); extern PetscReal soly(PetscReal); extern PetscReal solz(PetscReal); int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt time_steps = 100,steps; Vec global; PetscReal dt,ftime; TS ts; Mat A = 0,S; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL,"-time",&time_steps,NULL);CHKERRQ(ierr); /* set initial conditions */ ierr = VecCreate(PETSC_COMM_WORLD,&global);CHKERRQ(ierr); ierr = VecSetSizes(global,PETSC_DECIDE,3);CHKERRQ(ierr); ierr = VecSetFromOptions(global);CHKERRQ(ierr); ierr = Initial(global,NULL);CHKERRQ(ierr); /* make timestep context */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSMonitorSet(ts,Monitor,NULL,NULL);CHKERRQ(ierr); dt = 0.001; /* The user provides the RHS and Jacobian */ ierr = TSSetRHSFunction(ts,NULL,RHSFunction,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,3,3);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = RHSJacobian(ts,0.0,global,A,A,NULL);CHKERRQ(ierr); ierr = TSSetRHSJacobian(ts,A,A,RHSJacobian,NULL);CHKERRQ(ierr); ierr = MatCreateShell(PETSC_COMM_WORLD,3,3,3,3,NULL,&S);CHKERRQ(ierr); ierr = MatShellSetOperation(S,MATOP_MULT,(void (*)(void))MyMatMult);CHKERRQ(ierr); ierr = TSSetRHSJacobian(ts,S,A,RHSJacobian,NULL);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSetTimeStep(ts,dt);CHKERRQ(ierr); ierr = TSSetMaxSteps(ts,time_steps);CHKERRQ(ierr); ierr = TSSetMaxTime(ts,1);CHKERRQ(ierr); ierr = TSSetSolution(ts,global);CHKERRQ(ierr); ierr = TSSolve(ts,global);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetStepNumber(ts,&steps);CHKERRQ(ierr); /* free the memories */ ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&S);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; } PetscErrorCode MyMatMult(Mat S,Vec x,Vec y) { PetscErrorCode ierr; const PetscScalar *inptr; PetscScalar *outptr; PetscFunctionBegin; ierr = VecGetArrayRead(x,&inptr);CHKERRQ(ierr); ierr = VecGetArrayWrite(y,&outptr);CHKERRQ(ierr); outptr[0] = 2.0*inptr[0]+inptr[1]; outptr[1] = inptr[0]+2.0*inptr[1]+inptr[2]; outptr[2] = inptr[1]+2.0*inptr[2]; ierr = VecRestoreArrayRead(x,&inptr);CHKERRQ(ierr); ierr = VecRestoreArrayWrite(y,&outptr);CHKERRQ(ierr); PetscFunctionReturn(0); } /* this test problem has initial values (1,1,1). */ PetscErrorCode Initial(Vec global,void *ctx) { PetscScalar *localptr; PetscInt i,mybase,myend,locsize; PetscErrorCode ierr; /* determine starting point of each processor */ ierr = VecGetOwnershipRange(global,&mybase,&myend);CHKERRQ(ierr); ierr = VecGetLocalSize(global,&locsize);CHKERRQ(ierr); /* Initialize the array */ ierr = VecGetArrayWrite(global,&localptr);CHKERRQ(ierr); for (i=0; i