xref: /petsc/src/ts/impls/implicit/theta/theta.c (revision 316643e75493b436315f0c4d6fd4da08687498f7)
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