xref: /petsc/src/ts/impls/implicit/theta/theta.c (revision 5a3a76d07e72bd733c23cdbf132d31c2a5ff3d88)
1316643e7SJed Brown /*
2316643e7SJed Brown   Code for timestepping with implicit Theta method
3316643e7SJed Brown */
4c6db04a5SJed Brown #include <private/tsimpl.h>                /*I   "petscts.h"   I*/
5316643e7SJed Brown 
6316643e7SJed Brown typedef struct {
7316643e7SJed Brown   Vec       X,Xdot;                   /* Storage for one stage */
8eb284becSJed Brown   Vec       affine;                   /* Affine vector needed for residual at beginning of step */
9ace3abfcSBarry Smith   PetscBool extrapolate;
10eb284becSJed Brown   PetscBool endpoint;
11316643e7SJed Brown   PetscReal Theta;
12316643e7SJed Brown   PetscReal shift;
13316643e7SJed Brown   PetscReal stage_time;
14316643e7SJed Brown } TS_Theta;
15316643e7SJed Brown 
16316643e7SJed Brown #undef __FUNCT__
17316643e7SJed Brown #define __FUNCT__ "TSStep_Theta"
18193ac0bcSJed Brown static PetscErrorCode TSStep_Theta(TS ts)
19316643e7SJed Brown {
20316643e7SJed Brown   TS_Theta       *th = (TS_Theta*)ts->data;
21b70ae86eSJed Brown   PetscInt       its,lits;
222b5a38e1SLisandro Dalcin   PetscErrorCode ierr;
23316643e7SJed Brown 
24316643e7SJed Brown   PetscFunctionBegin;
25193ac0bcSJed Brown   ts->time_step = ts->next_time_step;
26eb284becSJed Brown   th->stage_time = ts->ptime + (th->endpoint ? 1. : th->Theta)*ts->time_step;
27316643e7SJed Brown   th->shift = 1./(th->Theta*ts->time_step);
28316643e7SJed Brown 
29eb284becSJed Brown   if (th->endpoint) {           /* This formulation assumes linear time-independent mass matrix */
30eb284becSJed Brown     ierr = VecZeroEntries(th->Xdot);CHKERRQ(ierr);
31eb284becSJed Brown     if (!th->affine) {ierr = VecDuplicate(ts->vec_sol,&th->affine);CHKERRQ(ierr);}
32eb284becSJed Brown     ierr = TSComputeIFunction(ts,ts->ptime,ts->vec_sol,th->Xdot,th->affine,PETSC_FALSE);CHKERRQ(ierr);
33eb284becSJed Brown     ierr = VecScale(th->affine,(th->Theta-1.)/th->Theta);CHKERRQ(ierr);
34eb284becSJed Brown   }
35ace68cafSJed Brown   if (th->extrapolate) {
362b5a38e1SLisandro Dalcin     ierr = VecWAXPY(th->X,1./th->shift,th->Xdot,ts->vec_sol);CHKERRQ(ierr);
37ace68cafSJed Brown   } else {
382b5a38e1SLisandro Dalcin     ierr = VecCopy(ts->vec_sol,th->X);CHKERRQ(ierr);
39ace68cafSJed Brown   }
40eb284becSJed Brown   ierr = SNESSolve(ts->snes,th->affine,th->X);CHKERRQ(ierr);
41316643e7SJed Brown   ierr = SNESGetIterationNumber(ts->snes,&its);CHKERRQ(ierr);
42316643e7SJed Brown   ierr = SNESGetLinearSolveIterations(ts->snes,&lits);CHKERRQ(ierr);
43316643e7SJed Brown   ts->nonlinear_its += its; ts->linear_its += lits;
442b5a38e1SLisandro Dalcin 
45eb284becSJed Brown   if (th->endpoint) {
46eb284becSJed Brown     ierr = VecCopy(th->X,ts->vec_sol);CHKERRQ(ierr);
47eb284becSJed Brown   } else {
482b5a38e1SLisandro Dalcin     ierr = VecAXPBYPCZ(th->Xdot,-th->shift,th->shift,0,ts->vec_sol,th->X);CHKERRQ(ierr);
492b5a38e1SLisandro Dalcin     ierr = VecAXPY(ts->vec_sol,ts->time_step,th->Xdot);CHKERRQ(ierr);
50eb284becSJed Brown   }
512b5a38e1SLisandro Dalcin   ts->ptime          += ts->time_step;
52193ac0bcSJed Brown   ts->next_time_step  = ts->time_step;
53316643e7SJed Brown   ts->steps++;
54316643e7SJed Brown   PetscFunctionReturn(0);
55316643e7SJed Brown }
56316643e7SJed Brown 
57cd652676SJed Brown #undef __FUNCT__
58cd652676SJed Brown #define __FUNCT__ "TSInterpolate_Theta"
59cd652676SJed Brown static PetscErrorCode TSInterpolate_Theta(TS ts,PetscReal t,Vec X)
60cd652676SJed Brown {
61cd652676SJed Brown   TS_Theta       *th = (TS_Theta*)ts->data;
62*5a3a76d0SJed Brown   PetscReal      alpha = t - ts->ptime;
63cd652676SJed Brown   PetscErrorCode ierr;
64cd652676SJed Brown 
65cd652676SJed Brown   PetscFunctionBegin;
66a43b19c4SJed Brown   ierr = VecCopy(ts->vec_sol,th->X);CHKERRQ(ierr);
67*5a3a76d0SJed Brown   if (th->endpoint) alpha *= th->Theta;
68*5a3a76d0SJed Brown   ierr = VecWAXPY(X,alpha,th->Xdot,th->X);CHKERRQ(ierr);
69cd652676SJed Brown   PetscFunctionReturn(0);
70cd652676SJed Brown }
71cd652676SJed Brown 
72316643e7SJed Brown /*------------------------------------------------------------*/
73316643e7SJed Brown #undef __FUNCT__
74277b19d0SLisandro Dalcin #define __FUNCT__ "TSReset_Theta"
75277b19d0SLisandro Dalcin static PetscErrorCode TSReset_Theta(TS ts)
76316643e7SJed Brown {
77316643e7SJed Brown   TS_Theta       *th = (TS_Theta*)ts->data;
78316643e7SJed Brown   PetscErrorCode  ierr;
79316643e7SJed Brown 
80316643e7SJed Brown   PetscFunctionBegin;
816bf464f9SBarry Smith   ierr = VecDestroy(&th->X);CHKERRQ(ierr);
826bf464f9SBarry Smith   ierr = VecDestroy(&th->Xdot);CHKERRQ(ierr);
83eb284becSJed Brown   ierr = VecDestroy(&th->affine);CHKERRQ(ierr);
84277b19d0SLisandro Dalcin   PetscFunctionReturn(0);
85277b19d0SLisandro Dalcin }
86277b19d0SLisandro Dalcin 
87277b19d0SLisandro Dalcin #undef __FUNCT__
88277b19d0SLisandro Dalcin #define __FUNCT__ "TSDestroy_Theta"
89277b19d0SLisandro Dalcin static PetscErrorCode TSDestroy_Theta(TS ts)
90277b19d0SLisandro Dalcin {
91277b19d0SLisandro Dalcin   PetscErrorCode  ierr;
92277b19d0SLisandro Dalcin 
93277b19d0SLisandro Dalcin   PetscFunctionBegin;
94277b19d0SLisandro Dalcin   ierr = TSReset_Theta(ts);CHKERRQ(ierr);
95277b19d0SLisandro Dalcin   ierr = PetscFree(ts->data);CHKERRQ(ierr);
96335f802eSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSThetaGetTheta_C","",PETSC_NULL);CHKERRQ(ierr);
97335f802eSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSThetaSetTheta_C","",PETSC_NULL);CHKERRQ(ierr);
98eb284becSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSThetaSetEndpoint_C","",PETSC_NULL);CHKERRQ(ierr);
99316643e7SJed Brown   PetscFunctionReturn(0);
100316643e7SJed Brown }
101316643e7SJed Brown 
102316643e7SJed Brown /*
103316643e7SJed Brown   This defines the nonlinear equation that is to be solved with SNES
1042b5a38e1SLisandro Dalcin   G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0
105316643e7SJed Brown */
106316643e7SJed Brown #undef __FUNCT__
1070f5c6efeSJed Brown #define __FUNCT__ "SNESTSFormFunction_Theta"
1080f5c6efeSJed Brown static PetscErrorCode SNESTSFormFunction_Theta(SNES snes,Vec x,Vec y,TS ts)
109316643e7SJed Brown {
110316643e7SJed Brown   TS_Theta       *th = (TS_Theta*)ts->data;
111316643e7SJed Brown   PetscErrorCode ierr;
112316643e7SJed Brown 
113316643e7SJed Brown   PetscFunctionBegin;
114*5a3a76d0SJed Brown   /* When using the endpoint variant, this is actually 1/Theta * Xdot */
1152b5a38e1SLisandro Dalcin   ierr = VecAXPBYPCZ(th->Xdot,-th->shift,th->shift,0,ts->vec_sol,x);CHKERRQ(ierr);
116214bc6a2SJed Brown   ierr = TSComputeIFunction(ts,th->stage_time,x,th->Xdot,y,PETSC_FALSE);CHKERRQ(ierr);
117316643e7SJed Brown   PetscFunctionReturn(0);
118316643e7SJed Brown }
119316643e7SJed Brown 
120316643e7SJed Brown #undef __FUNCT__
1210f5c6efeSJed Brown #define __FUNCT__ "SNESTSFormJacobian_Theta"
1220f5c6efeSJed Brown static PetscErrorCode SNESTSFormJacobian_Theta(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *str,TS ts)
123316643e7SJed Brown {
124316643e7SJed Brown   TS_Theta       *th = (TS_Theta*)ts->data;
125316643e7SJed Brown   PetscErrorCode ierr;
126316643e7SJed Brown 
127316643e7SJed Brown   PetscFunctionBegin;
1280f5c6efeSJed Brown   /* th->Xdot has already been computed in SNESTSFormFunction_Theta (SNES guarantees this) */
129214bc6a2SJed Brown   ierr = TSComputeIJacobian(ts,th->stage_time,x,th->Xdot,th->shift,A,B,str,PETSC_FALSE);CHKERRQ(ierr);
130316643e7SJed Brown   PetscFunctionReturn(0);
131316643e7SJed Brown }
132316643e7SJed Brown 
133316643e7SJed Brown 
134316643e7SJed Brown #undef __FUNCT__
135316643e7SJed Brown #define __FUNCT__ "TSSetUp_Theta"
136316643e7SJed Brown static PetscErrorCode TSSetUp_Theta(TS ts)
137316643e7SJed Brown {
138316643e7SJed Brown   TS_Theta       *th = (TS_Theta*)ts->data;
139316643e7SJed Brown   PetscErrorCode ierr;
140316643e7SJed Brown 
141316643e7SJed Brown   PetscFunctionBegin;
142316643e7SJed Brown   ierr = VecDuplicate(ts->vec_sol,&th->X);CHKERRQ(ierr);
143316643e7SJed Brown   ierr = VecDuplicate(ts->vec_sol,&th->Xdot);CHKERRQ(ierr);
144316643e7SJed Brown   PetscFunctionReturn(0);
145316643e7SJed Brown }
146316643e7SJed Brown /*------------------------------------------------------------*/
147316643e7SJed Brown 
148316643e7SJed Brown #undef __FUNCT__
149316643e7SJed Brown #define __FUNCT__ "TSSetFromOptions_Theta"
150316643e7SJed Brown static PetscErrorCode TSSetFromOptions_Theta(TS ts)
151316643e7SJed Brown {
152316643e7SJed Brown   TS_Theta       *th = (TS_Theta*)ts->data;
153316643e7SJed Brown   PetscErrorCode ierr;
154316643e7SJed Brown 
155316643e7SJed Brown   PetscFunctionBegin;
156d73342a9SJed Brown   ierr = PetscOptionsHead("Theta ODE solver options");CHKERRQ(ierr);
157316643e7SJed Brown   {
158316643e7SJed Brown     ierr = PetscOptionsReal("-ts_theta_theta","Location of stage (0<Theta<=1)","TSThetaSetTheta",th->Theta,&th->Theta,PETSC_NULL);CHKERRQ(ierr);
159acfcf0e5SJed Brown     ierr = PetscOptionsBool("-ts_theta_extrapolate","Extrapolate stage solution from previous solution (sometimes unstable)","TSThetaSetExtrapolate",th->extrapolate,&th->extrapolate,PETSC_NULL);CHKERRQ(ierr);
160eb284becSJed Brown     ierr = PetscOptionsBool("-ts_theta_endpoint","Use the endpoint instead of midpoint form of the Theta method","TSThetaSetEndpoint",th->endpoint,&th->endpoint,PETSC_NULL);CHKERRQ(ierr);
161316643e7SJed Brown   }
162316643e7SJed Brown   ierr = PetscOptionsTail();CHKERRQ(ierr);
163316643e7SJed Brown   PetscFunctionReturn(0);
164316643e7SJed Brown }
165316643e7SJed Brown 
166316643e7SJed Brown #undef __FUNCT__
167316643e7SJed Brown #define __FUNCT__ "TSView_Theta"
168316643e7SJed Brown static PetscErrorCode TSView_Theta(TS ts,PetscViewer viewer)
169316643e7SJed Brown {
170316643e7SJed Brown   TS_Theta       *th = (TS_Theta*)ts->data;
171ace3abfcSBarry Smith   PetscBool       iascii;
172316643e7SJed Brown   PetscErrorCode  ierr;
173316643e7SJed Brown 
174316643e7SJed Brown   PetscFunctionBegin;
1752692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
176316643e7SJed Brown   if (iascii) {
177316643e7SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Theta=%G\n",th->Theta);CHKERRQ(ierr);
178ace68cafSJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  Extrapolation=%s\n",th->extrapolate?"yes":"no");CHKERRQ(ierr);
179316643e7SJed Brown   }
180316643e7SJed Brown   PetscFunctionReturn(0);
181316643e7SJed Brown }
182316643e7SJed Brown 
1830de4c49aSJed Brown EXTERN_C_BEGIN
1840de4c49aSJed Brown #undef __FUNCT__
1850de4c49aSJed Brown #define __FUNCT__ "TSThetaGetTheta_Theta"
1867087cfbeSBarry Smith PetscErrorCode  TSThetaGetTheta_Theta(TS ts,PetscReal *theta)
1870de4c49aSJed Brown {
1880de4c49aSJed Brown   TS_Theta *th = (TS_Theta*)ts->data;
1890de4c49aSJed Brown 
1900de4c49aSJed Brown   PetscFunctionBegin;
1910de4c49aSJed Brown   *theta = th->Theta;
1920de4c49aSJed Brown   PetscFunctionReturn(0);
1930de4c49aSJed Brown }
1940de4c49aSJed Brown 
1950de4c49aSJed Brown #undef __FUNCT__
1960de4c49aSJed Brown #define __FUNCT__ "TSThetaSetTheta_Theta"
1977087cfbeSBarry Smith PetscErrorCode  TSThetaSetTheta_Theta(TS ts,PetscReal theta)
1980de4c49aSJed Brown {
1990de4c49aSJed Brown   TS_Theta *th = (TS_Theta*)ts->data;
2000de4c49aSJed Brown 
2010de4c49aSJed Brown   PetscFunctionBegin;
202e7be1afaSJed Brown   if (theta <= 0 || 1 < theta) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Theta %G not in range (0,1]",theta);
2030de4c49aSJed Brown   th->Theta = theta;
2040de4c49aSJed Brown   PetscFunctionReturn(0);
2050de4c49aSJed Brown }
206eb284becSJed Brown 
207eb284becSJed Brown #undef __FUNCT__
208eb284becSJed Brown #define __FUNCT__ "TSThetaSetEndpoint_Theta"
209eb284becSJed Brown PetscErrorCode  TSThetaSetEndpoint_Theta(TS ts,PetscBool flg)
210eb284becSJed Brown {
211eb284becSJed Brown   TS_Theta *th = (TS_Theta*)ts->data;
212eb284becSJed Brown 
213eb284becSJed Brown   PetscFunctionBegin;
214eb284becSJed Brown   th->endpoint = flg;
215eb284becSJed Brown   PetscFunctionReturn(0);
216eb284becSJed Brown }
2170de4c49aSJed Brown EXTERN_C_END
2180de4c49aSJed Brown 
219316643e7SJed Brown /* ------------------------------------------------------------ */
220316643e7SJed Brown /*MC
22196f5712cSJed Brown       TSTHETA - DAE solver using the implicit Theta method
222316643e7SJed Brown 
223316643e7SJed Brown    Level: beginner
224316643e7SJed Brown 
225eb284becSJed Brown    Notes:
226eb284becSJed Brown    This method can be applied to DAE.
227eb284becSJed Brown 
228eb284becSJed Brown    This method is cast as a 1-stage implicit Runge-Kutta method.
229eb284becSJed Brown 
230eb284becSJed Brown .vb
231eb284becSJed Brown   Theta | Theta
232eb284becSJed Brown   -------------
233eb284becSJed Brown         |  1
234eb284becSJed Brown .ve
235eb284becSJed Brown 
236eb284becSJed Brown    For the default Theta=0.5, this is also known as the implicit midpoint rule.
237eb284becSJed Brown 
238eb284becSJed Brown    When the endpoint variant is chosen, the method becomes a 2-stage method with first stage explicit:
239eb284becSJed Brown 
240eb284becSJed Brown .vb
241eb284becSJed Brown   0 | 0         0
242eb284becSJed Brown   1 | 1-Theta   Theta
243eb284becSJed Brown   -------------------
244eb284becSJed Brown     | 1-Theta   Theta
245eb284becSJed Brown .ve
246eb284becSJed Brown 
247eb284becSJed Brown    For the default Theta=0.5, this is the trapezoid rule (also known as Crank-Nicolson, see TSCN).
248eb284becSJed Brown 
249eb284becSJed Brown    To apply a diagonally implicit RK method to DAE, the stage formula
250eb284becSJed Brown 
251eb284becSJed Brown $  Y_i = X + h sum_j a_ij Y'_j
252eb284becSJed Brown 
253eb284becSJed Brown    is interpreted as a formula for Y'_i in terms of Y_i and known stuff (Y'_j, j<i)
254eb284becSJed Brown 
255eb284becSJed Brown .seealso:  TSCreate(), TS, TSSetType(), TSCN, TSBEULER, TSThetaSetTheta(), TSThetaSetEndpoint()
256316643e7SJed Brown 
257316643e7SJed Brown M*/
258316643e7SJed Brown EXTERN_C_BEGIN
259316643e7SJed Brown #undef __FUNCT__
260316643e7SJed Brown #define __FUNCT__ "TSCreate_Theta"
2617087cfbeSBarry Smith PetscErrorCode  TSCreate_Theta(TS ts)
262316643e7SJed Brown {
263316643e7SJed Brown   TS_Theta       *th;
264316643e7SJed Brown   PetscErrorCode ierr;
265316643e7SJed Brown 
266316643e7SJed Brown   PetscFunctionBegin;
267277b19d0SLisandro Dalcin   ts->ops->reset          = TSReset_Theta;
268316643e7SJed Brown   ts->ops->destroy        = TSDestroy_Theta;
269316643e7SJed Brown   ts->ops->view           = TSView_Theta;
270316643e7SJed Brown   ts->ops->setup          = TSSetUp_Theta;
271316643e7SJed Brown   ts->ops->step           = TSStep_Theta;
272cd652676SJed Brown   ts->ops->interpolate    = TSInterpolate_Theta;
273316643e7SJed Brown   ts->ops->setfromoptions = TSSetFromOptions_Theta;
2740f5c6efeSJed Brown   ts->ops->snesfunction   = SNESTSFormFunction_Theta;
2750f5c6efeSJed Brown   ts->ops->snesjacobian   = SNESTSFormJacobian_Theta;
276316643e7SJed Brown 
277316643e7SJed Brown   ierr = PetscNewLog(ts,TS_Theta,&th);CHKERRQ(ierr);
278316643e7SJed Brown   ts->data = (void*)th;
279316643e7SJed Brown 
2806f700aefSJed Brown   th->extrapolate = PETSC_FALSE;
281316643e7SJed Brown   th->Theta       = 0.5;
282316643e7SJed Brown 
2830de4c49aSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSThetaGetTheta_C","TSThetaGetTheta_Theta",TSThetaGetTheta_Theta);CHKERRQ(ierr);
2840de4c49aSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSThetaSetTheta_C","TSThetaSetTheta_Theta",TSThetaSetTheta_Theta);CHKERRQ(ierr);
285eb284becSJed Brown   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSThetaSetEndpoint_C","TSThetaSetEndpoint_Theta",TSThetaSetEndpoint_Theta);CHKERRQ(ierr);
286316643e7SJed Brown   PetscFunctionReturn(0);
287316643e7SJed Brown }
288316643e7SJed Brown EXTERN_C_END
2890de4c49aSJed Brown 
2900de4c49aSJed Brown #undef __FUNCT__
2910de4c49aSJed Brown #define __FUNCT__ "TSThetaGetTheta"
2920de4c49aSJed Brown /*@
2930de4c49aSJed Brown   TSThetaGetTheta - Get the abscissa of the stage in (0,1].
2940de4c49aSJed Brown 
2950de4c49aSJed Brown   Not Collective
2960de4c49aSJed Brown 
2970de4c49aSJed Brown   Input Parameter:
2980de4c49aSJed Brown .  ts - timestepping context
2990de4c49aSJed Brown 
3000de4c49aSJed Brown   Output Parameter:
3010de4c49aSJed Brown .  theta - stage abscissa
3020de4c49aSJed Brown 
3030de4c49aSJed Brown   Note:
3040de4c49aSJed Brown   Use of this function is normally only required to hack TSTHETA to use a modified integration scheme.
3050de4c49aSJed Brown 
3060de4c49aSJed Brown   Level: Advanced
3070de4c49aSJed Brown 
3080de4c49aSJed Brown .seealso: TSThetaSetTheta()
3090de4c49aSJed Brown @*/
3107087cfbeSBarry Smith PetscErrorCode  TSThetaGetTheta(TS ts,PetscReal *theta)
3110de4c49aSJed Brown {
3124ac538c5SBarry Smith   PetscErrorCode ierr;
3130de4c49aSJed Brown 
3140de4c49aSJed Brown   PetscFunctionBegin;
315afb20b64SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3160de4c49aSJed Brown   PetscValidPointer(theta,2);
3174ac538c5SBarry Smith   ierr = PetscUseMethod(ts,"TSThetaGetTheta_C",(TS,PetscReal*),(ts,theta));CHKERRQ(ierr);
3180de4c49aSJed Brown   PetscFunctionReturn(0);
3190de4c49aSJed Brown }
3200de4c49aSJed Brown 
3210de4c49aSJed Brown #undef __FUNCT__
3220de4c49aSJed Brown #define __FUNCT__ "TSThetaSetTheta"
3230de4c49aSJed Brown /*@
3240de4c49aSJed Brown   TSThetaSetTheta - Set the abscissa of the stage in (0,1].
3250de4c49aSJed Brown 
3260de4c49aSJed Brown   Not Collective
3270de4c49aSJed Brown 
3280de4c49aSJed Brown   Input Parameter:
3290de4c49aSJed Brown +  ts - timestepping context
3300de4c49aSJed Brown -  theta - stage abscissa
3310de4c49aSJed Brown 
3320de4c49aSJed Brown   Options Database:
3330de4c49aSJed Brown .  -ts_theta_theta <theta>
3340de4c49aSJed Brown 
3350de4c49aSJed Brown   Level: Intermediate
3360de4c49aSJed Brown 
3370de4c49aSJed Brown .seealso: TSThetaGetTheta()
3380de4c49aSJed Brown @*/
3397087cfbeSBarry Smith PetscErrorCode  TSThetaSetTheta(TS ts,PetscReal theta)
3400de4c49aSJed Brown {
3414ac538c5SBarry Smith   PetscErrorCode ierr;
3420de4c49aSJed Brown 
3430de4c49aSJed Brown   PetscFunctionBegin;
344afb20b64SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3454ac538c5SBarry Smith   ierr = PetscTryMethod(ts,"TSThetaSetTheta_C",(TS,PetscReal),(ts,theta));CHKERRQ(ierr);
3460de4c49aSJed Brown   PetscFunctionReturn(0);
3470de4c49aSJed Brown }
348f33bbcb6SJed Brown 
349eb284becSJed Brown #undef __FUNCT__
350eb284becSJed Brown #define __FUNCT__ "TSThetaSetEndpoint"
351eb284becSJed Brown /*@
352eb284becSJed Brown   TSThetaSetEndpoint - Sets whether to use the endpoint variant of the method (e.g. trapezoid/Crank-Nicolson instead of midpoint rule).
353eb284becSJed Brown 
354eb284becSJed Brown   Not Collective
355eb284becSJed Brown 
356eb284becSJed Brown   Input Parameter:
357eb284becSJed Brown +  ts - timestepping context
358eb284becSJed Brown -  flg - PETSC_TRUE to use the endpoint variant
359eb284becSJed Brown 
360eb284becSJed Brown   Options Database:
361eb284becSJed Brown .  -ts_theta_endpoint <flg>
362eb284becSJed Brown 
363eb284becSJed Brown   Level: Intermediate
364eb284becSJed Brown 
365eb284becSJed Brown .seealso: TSTHETA, TSCN
366eb284becSJed Brown @*/
367eb284becSJed Brown PetscErrorCode TSThetaSetEndpoint(TS ts,PetscBool flg)
368eb284becSJed Brown {
369eb284becSJed Brown   PetscErrorCode ierr;
370eb284becSJed Brown 
371eb284becSJed Brown   PetscFunctionBegin;
372eb284becSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
373eb284becSJed Brown   ierr = PetscTryMethod(ts,"TSThetaSetEndpoint_C",(TS,PetscBool),(ts,flg));CHKERRQ(ierr);
374eb284becSJed Brown   PetscFunctionReturn(0);
375eb284becSJed Brown }
376eb284becSJed Brown 
377f33bbcb6SJed Brown /*
378f33bbcb6SJed Brown  * TSBEULER and TSCN are straightforward specializations of TSTHETA.
379f33bbcb6SJed Brown  * The creation functions for these specializations are below.
380f33bbcb6SJed Brown  */
381f33bbcb6SJed Brown 
382f33bbcb6SJed Brown #undef __FUNCT__
383f33bbcb6SJed Brown #define __FUNCT__ "TSView_BEuler"
384f33bbcb6SJed Brown static PetscErrorCode TSView_BEuler(TS ts,PetscViewer viewer)
385f33bbcb6SJed Brown {
386f33bbcb6SJed Brown   PetscFunctionBegin;
387f33bbcb6SJed Brown   PetscFunctionReturn(0);
388f33bbcb6SJed Brown }
389f33bbcb6SJed Brown 
390f33bbcb6SJed Brown /*MC
391f33bbcb6SJed Brown       TSBEULER - ODE solver using the implicit backward Euler method
392f33bbcb6SJed Brown 
393f33bbcb6SJed Brown   Level: beginner
394f33bbcb6SJed Brown 
395f33bbcb6SJed Brown .seealso:  TSCreate(), TS, TSSetType(), TSEULER, TSCN, TSTHETA
396f33bbcb6SJed Brown 
397f33bbcb6SJed Brown M*/
398f33bbcb6SJed Brown EXTERN_C_BEGIN
399f33bbcb6SJed Brown #undef __FUNCT__
400f33bbcb6SJed Brown #define __FUNCT__ "TSCreate_BEuler"
401f33bbcb6SJed Brown PetscErrorCode  TSCreate_BEuler(TS ts)
402f33bbcb6SJed Brown {
403f33bbcb6SJed Brown   PetscErrorCode ierr;
404f33bbcb6SJed Brown 
405f33bbcb6SJed Brown   PetscFunctionBegin;
406f33bbcb6SJed Brown   ierr = TSCreate_Theta(ts);CHKERRQ(ierr);
407f33bbcb6SJed Brown   ierr = TSThetaSetTheta(ts,1.0);CHKERRQ(ierr);
408f33bbcb6SJed Brown   ts->ops->view = TSView_BEuler;
409f33bbcb6SJed Brown   PetscFunctionReturn(0);
410f33bbcb6SJed Brown }
411f33bbcb6SJed Brown EXTERN_C_END
412f33bbcb6SJed Brown 
413f33bbcb6SJed Brown #undef __FUNCT__
414f33bbcb6SJed Brown #define __FUNCT__ "TSView_CN"
415f33bbcb6SJed Brown static PetscErrorCode TSView_CN(TS ts,PetscViewer viewer)
416f33bbcb6SJed Brown {
417f33bbcb6SJed Brown   PetscFunctionBegin;
418f33bbcb6SJed Brown   PetscFunctionReturn(0);
419f33bbcb6SJed Brown }
420f33bbcb6SJed Brown 
421f33bbcb6SJed Brown /*MC
422f33bbcb6SJed Brown       TSCN - ODE solver using the implicit Crank-Nicolson method.
423f33bbcb6SJed Brown 
424f33bbcb6SJed Brown   Level: beginner
425f33bbcb6SJed Brown 
426f33bbcb6SJed Brown   Notes:
427f33bbcb6SJed Brown   TSCN is equivalent to TSTHETA with Theta=0.5
428f33bbcb6SJed Brown 
429f33bbcb6SJed Brown .seealso:  TSCreate(), TS, TSSetType(), TSBEULER, TSTHETA
430f33bbcb6SJed Brown 
431f33bbcb6SJed Brown M*/
432f33bbcb6SJed Brown EXTERN_C_BEGIN
433f33bbcb6SJed Brown #undef __FUNCT__
434f33bbcb6SJed Brown #define __FUNCT__ "TSCreate_CN"
435f33bbcb6SJed Brown PetscErrorCode  TSCreate_CN(TS ts)
436f33bbcb6SJed Brown {
437f33bbcb6SJed Brown   PetscErrorCode ierr;
438f33bbcb6SJed Brown 
439f33bbcb6SJed Brown   PetscFunctionBegin;
440f33bbcb6SJed Brown   ierr = TSCreate_Theta(ts);CHKERRQ(ierr);
441f33bbcb6SJed Brown   ierr = TSThetaSetTheta(ts,0.5);CHKERRQ(ierr);
442eb284becSJed Brown   ierr = TSThetaSetEndpoint(ts,PETSC_TRUE);CHKERRQ(ierr);
443f33bbcb6SJed Brown   ts->ops->view = TSView_CN;
444f33bbcb6SJed Brown   PetscFunctionReturn(0);
445f33bbcb6SJed Brown }
446f33bbcb6SJed Brown EXTERN_C_END
447