1*316643e7SJed Brown #define PETSCTS_DLL 2*316643e7SJed Brown 3*316643e7SJed Brown /* 4*316643e7SJed Brown Code for timestepping with implicit Theta method 5*316643e7SJed Brown 6*316643e7SJed Brown Notes: 7*316643e7SJed Brown This method can be applied to DAE. 8*316643e7SJed Brown 9*316643e7SJed Brown This method is cast as a 1-stage implicit Runge-Kutta method. 10*316643e7SJed Brown 11*316643e7SJed Brown Theta | Theta 12*316643e7SJed Brown ------------- 13*316643e7SJed Brown | 1 14*316643e7SJed Brown 15*316643e7SJed Brown To apply a diagonally implicit RK method to DAE, the stage formula 16*316643e7SJed Brown 17*316643e7SJed Brown X_i = x + h sum_j a_ij X'_j 18*316643e7SJed Brown 19*316643e7SJed Brown is interpreted as a formula for X'_i in terms of X_i and known stuff (X'_j, j<i) 20*316643e7SJed Brown */ 21*316643e7SJed Brown #include "private/tsimpl.h" /*I "petscts.h" I*/ 22*316643e7SJed Brown 23*316643e7SJed Brown typedef struct { 24*316643e7SJed Brown Vec Xold; 25*316643e7SJed Brown Vec X,Xdot; /* Storage for one stage */ 26*316643e7SJed Brown Vec res; /* DAE residuals */ 27*316643e7SJed Brown PetscReal Theta; 28*316643e7SJed Brown PetscReal shift; 29*316643e7SJed Brown PetscReal stage_time; 30*316643e7SJed Brown } TS_Theta; 31*316643e7SJed Brown 32*316643e7SJed Brown #undef __FUNCT__ 33*316643e7SJed Brown #define __FUNCT__ "TSStep_Theta" 34*316643e7SJed Brown static PetscErrorCode TSStep_Theta(TS ts,PetscInt *steps,PetscReal *ptime) 35*316643e7SJed Brown { 36*316643e7SJed Brown Vec sol = ts->vec_sol; 37*316643e7SJed Brown PetscErrorCode ierr; 38*316643e7SJed Brown PetscInt i,max_steps = ts->max_steps,its,lits; 39*316643e7SJed Brown TS_Theta *th = (TS_Theta*)ts->data; 40*316643e7SJed Brown 41*316643e7SJed Brown PetscFunctionBegin; 42*316643e7SJed Brown *steps = -ts->steps; 43*316643e7SJed Brown ierr = TSMonitor(ts,ts->steps,ts->ptime,sol);CHKERRQ(ierr); 44*316643e7SJed Brown 45*316643e7SJed Brown for (i=0; i<max_steps; i++) { 46*316643e7SJed Brown if (ts->ptime + ts->time_step > ts->max_time) break; 47*316643e7SJed Brown th->stage_time = ts->ptime + th->Theta*ts->time_step; 48*316643e7SJed Brown th->shift = 1./(th->Theta*ts->time_step); 49*316643e7SJed Brown ts->ptime += ts->time_step; 50*316643e7SJed Brown 51*316643e7SJed Brown ierr = VecCopy(sol,th->Xold);CHKERRQ(ierr); /* Used within function evalutaion */ 52*316643e7SJed Brown ierr = VecWAXPY(th->X,1./th->shift,th->Xdot,sol);CHKERRQ(ierr); 53*316643e7SJed Brown ierr = SNESSolve(ts->snes,PETSC_NULL,th->X);CHKERRQ(ierr); 54*316643e7SJed Brown ierr = SNESGetIterationNumber(ts->snes,&its);CHKERRQ(ierr); 55*316643e7SJed Brown ierr = SNESGetLinearSolveIterations(ts->snes,&lits);CHKERRQ(ierr); 56*316643e7SJed Brown ts->nonlinear_its += its; ts->linear_its += lits; 57*316643e7SJed Brown ierr = VecAXPY(sol,ts->time_step,th->Xdot);CHKERRQ(ierr); 58*316643e7SJed Brown ts->steps++; 59*316643e7SJed Brown ierr = TSMonitor(ts,ts->steps,ts->ptime,sol);CHKERRQ(ierr); 60*316643e7SJed Brown } 61*316643e7SJed Brown 62*316643e7SJed Brown *steps += ts->steps; 63*316643e7SJed Brown *ptime = ts->ptime; 64*316643e7SJed Brown PetscFunctionReturn(0); 65*316643e7SJed Brown } 66*316643e7SJed Brown 67*316643e7SJed Brown /*------------------------------------------------------------*/ 68*316643e7SJed Brown #undef __FUNCT__ 69*316643e7SJed Brown #define __FUNCT__ "TSDestroy_Theta" 70*316643e7SJed Brown static PetscErrorCode TSDestroy_Theta(TS ts) 71*316643e7SJed Brown { 72*316643e7SJed Brown TS_Theta *th = (TS_Theta*)ts->data; 73*316643e7SJed Brown PetscErrorCode ierr; 74*316643e7SJed Brown 75*316643e7SJed Brown PetscFunctionBegin; 76*316643e7SJed Brown ierr = VecDestroy(th->Xold);CHKERRQ(ierr); 77*316643e7SJed Brown ierr = VecDestroy(th->X);CHKERRQ(ierr); 78*316643e7SJed Brown ierr = VecDestroy(th->Xdot);CHKERRQ(ierr); 79*316643e7SJed Brown ierr = VecDestroy(th->res);CHKERRQ(ierr); 80*316643e7SJed Brown ierr = PetscFree(th);CHKERRQ(ierr); 81*316643e7SJed Brown PetscFunctionReturn(0); 82*316643e7SJed Brown } 83*316643e7SJed Brown 84*316643e7SJed Brown /* 85*316643e7SJed Brown This defines the nonlinear equation that is to be solved with SNES 86*316643e7SJed Brown G(U) = F[t0+T*dt, U, (U-U0)*shift] = 0 87*316643e7SJed Brown */ 88*316643e7SJed Brown #undef __FUNCT__ 89*316643e7SJed Brown #define __FUNCT__ "TSThetaFunction" 90*316643e7SJed Brown static PetscErrorCode TSThetaFunction(SNES snes,Vec x,Vec y,void *ctx) 91*316643e7SJed Brown { 92*316643e7SJed Brown TS ts = (TS)ctx; 93*316643e7SJed Brown TS_Theta *th = (TS_Theta*)ts->data; 94*316643e7SJed Brown PetscErrorCode ierr; 95*316643e7SJed Brown 96*316643e7SJed Brown PetscFunctionBegin; 97*316643e7SJed Brown ierr = VecAXPBYPCZ(th->Xdot,-th->shift,th->shift,0,th->Xold,x);CHKERRQ(ierr); 98*316643e7SJed Brown ierr = TSComputeIFunction(ts,th->stage_time,x,th->Xdot,y);CHKERRQ(ierr); 99*316643e7SJed Brown PetscFunctionReturn(0); 100*316643e7SJed Brown } 101*316643e7SJed Brown 102*316643e7SJed Brown #undef __FUNCT__ 103*316643e7SJed Brown #define __FUNCT__ "TSThetaJacobian" 104*316643e7SJed Brown static PetscErrorCode TSThetaJacobian(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *str,void *ctx) 105*316643e7SJed Brown { 106*316643e7SJed Brown TS ts = (TS)ctx; 107*316643e7SJed Brown TS_Theta *th = (TS_Theta*)ts->data; 108*316643e7SJed Brown PetscErrorCode ierr; 109*316643e7SJed Brown 110*316643e7SJed Brown PetscFunctionBegin; 111*316643e7SJed Brown /* th->Xdot will have already been computed in TSThetaFunction */ 112*316643e7SJed Brown ierr = TSComputeIJacobian(ts,th->stage_time,x,th->Xdot,th->shift,A,B,str);CHKERRQ(ierr); 113*316643e7SJed Brown PetscFunctionReturn(0); 114*316643e7SJed Brown } 115*316643e7SJed Brown 116*316643e7SJed Brown 117*316643e7SJed Brown #undef __FUNCT__ 118*316643e7SJed Brown #define __FUNCT__ "TSSetUp_Theta" 119*316643e7SJed Brown static PetscErrorCode TSSetUp_Theta(TS ts) 120*316643e7SJed Brown { 121*316643e7SJed Brown TS_Theta *th = (TS_Theta*)ts->data; 122*316643e7SJed Brown PetscErrorCode ierr; 123*316643e7SJed Brown 124*316643e7SJed Brown PetscFunctionBegin; 125*316643e7SJed Brown ierr = VecDuplicate(ts->vec_sol,&th->Xold);CHKERRQ(ierr); 126*316643e7SJed Brown ierr = VecDuplicate(ts->vec_sol,&th->X);CHKERRQ(ierr); 127*316643e7SJed Brown ierr = VecDuplicate(ts->vec_sol,&th->Xdot);CHKERRQ(ierr); 128*316643e7SJed Brown ierr = VecDuplicate(ts->vec_sol,&th->res);CHKERRQ(ierr); 129*316643e7SJed Brown ierr = SNESSetFunction(ts->snes,th->res,TSThetaFunction,ts);CHKERRQ(ierr); 130*316643e7SJed Brown ierr = SNESSetJacobian(ts->snes,ts->A,ts->B,TSThetaJacobian,ts);CHKERRQ(ierr); 131*316643e7SJed Brown PetscFunctionReturn(0); 132*316643e7SJed Brown } 133*316643e7SJed Brown /*------------------------------------------------------------*/ 134*316643e7SJed Brown 135*316643e7SJed Brown #undef __FUNCT__ 136*316643e7SJed Brown #define __FUNCT__ "TSSetFromOptions_Theta" 137*316643e7SJed Brown static PetscErrorCode TSSetFromOptions_Theta(TS ts) 138*316643e7SJed Brown { 139*316643e7SJed Brown TS_Theta *th = (TS_Theta*)ts->data; 140*316643e7SJed Brown PetscErrorCode ierr; 141*316643e7SJed Brown 142*316643e7SJed Brown PetscFunctionBegin; 143*316643e7SJed Brown ierr = PetscOptionsHead("SUNDIALS ODE solver options");CHKERRQ(ierr); 144*316643e7SJed Brown { 145*316643e7SJed Brown ierr = PetscOptionsReal("-ts_theta_theta","Location of stage (0<Theta<=1)","TSThetaSetTheta",th->Theta,&th->Theta,PETSC_NULL);CHKERRQ(ierr); 146*316643e7SJed Brown } 147*316643e7SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 148*316643e7SJed Brown PetscFunctionReturn(0); 149*316643e7SJed Brown } 150*316643e7SJed Brown 151*316643e7SJed Brown #undef __FUNCT__ 152*316643e7SJed Brown #define __FUNCT__ "TSView_Theta" 153*316643e7SJed Brown static PetscErrorCode TSView_Theta(TS ts,PetscViewer viewer) 154*316643e7SJed Brown { 155*316643e7SJed Brown TS_Theta *th = (TS_Theta*)ts->data; 156*316643e7SJed Brown PetscTruth iascii; 157*316643e7SJed Brown PetscErrorCode ierr; 158*316643e7SJed Brown 159*316643e7SJed Brown PetscFunctionBegin; 160*316643e7SJed Brown ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 161*316643e7SJed Brown if (iascii) { 162*316643e7SJed Brown ierr = PetscViewerASCIIPrintf(viewer," Theta=%G\n",th->Theta);CHKERRQ(ierr); 163*316643e7SJed Brown } else { 164*316643e7SJed Brown SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for TS_Theta",((PetscObject)viewer)->type_name); 165*316643e7SJed Brown } 166*316643e7SJed Brown PetscFunctionReturn(0); 167*316643e7SJed Brown } 168*316643e7SJed Brown 169*316643e7SJed Brown /* ------------------------------------------------------------ */ 170*316643e7SJed Brown /*MC 171*316643e7SJed Brown TS_Theta - DAE solver using the implicit Theta method 172*316643e7SJed Brown 173*316643e7SJed Brown Level: beginner 174*316643e7SJed Brown 175*316643e7SJed Brown .seealso: TSCreate(), TS, TSSetType() 176*316643e7SJed Brown 177*316643e7SJed Brown M*/ 178*316643e7SJed Brown EXTERN_C_BEGIN 179*316643e7SJed Brown #undef __FUNCT__ 180*316643e7SJed Brown #define __FUNCT__ "TSCreate_Theta" 181*316643e7SJed Brown PetscErrorCode PETSCTS_DLLEXPORT TSCreate_Theta(TS ts) 182*316643e7SJed Brown { 183*316643e7SJed Brown TS_Theta *th; 184*316643e7SJed Brown PetscErrorCode ierr; 185*316643e7SJed Brown 186*316643e7SJed Brown PetscFunctionBegin; 187*316643e7SJed Brown ts->ops->destroy = TSDestroy_Theta; 188*316643e7SJed Brown ts->ops->view = TSView_Theta; 189*316643e7SJed Brown ts->ops->setup = TSSetUp_Theta; 190*316643e7SJed Brown ts->ops->step = TSStep_Theta; 191*316643e7SJed Brown ts->ops->setfromoptions = TSSetFromOptions_Theta; 192*316643e7SJed Brown 193*316643e7SJed Brown ierr = SNESCreate(((PetscObject)ts)->comm,&ts->snes);CHKERRQ(ierr); 194*316643e7SJed Brown ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 195*316643e7SJed Brown 196*316643e7SJed Brown ierr = PetscNewLog(ts,TS_Theta,&th);CHKERRQ(ierr); 197*316643e7SJed Brown ts->data = (void*)th; 198*316643e7SJed Brown 199*316643e7SJed Brown th->Theta = 0.5; 200*316643e7SJed Brown 201*316643e7SJed Brown PetscFunctionReturn(0); 202*316643e7SJed Brown } 203*316643e7SJed Brown EXTERN_C_END 204