Actual source code: alpha2.c

petsc-3.7.5 2017-01-01
Report Typos and Errors
  1: /*
  2:   Code for timestepping with implicit generalized-\alpha method
  3:   for second order systems.
  4: */
  5: #include <petsc/private/tsimpl.h>                /*I   "petscts.h"   I*/

  7: static PetscBool  cited = PETSC_FALSE;
  8: static const char citation[] =
  9:   "@article{Chung1993,\n"
 10:   "  title   = {A Time Integration Algorithm for Structural Dynamics with Improved Numerical Dissipation: The Generalized-$\\alpha$ Method},\n"
 11:   "  author  = {J. Chung, G. M. Hubert},\n"
 12:   "  journal = {ASME Journal of Applied Mechanics},\n"
 13:   "  volume  = {60},\n"
 14:   "  number  = {2},\n"
 15:   "  pages   = {371--375},\n"
 16:   "  year    = {1993},\n"
 17:   "  issn    = {0021-8936},\n"
 18:   "  doi     = {http://dx.doi.org/10.1115/1.2900803}\n}\n";

 20: typedef struct {
 21:   PetscReal stage_time;
 22:   PetscReal shift_V;
 23:   PetscReal shift_A;
 24:   PetscReal scale_F;
 25:   Vec       X0,Xa,X1;
 26:   Vec       V0,Va,V1;
 27:   Vec       A0,Aa,A1;

 29:   Vec       vec_dot;

 31:   PetscReal Alpha_m;
 32:   PetscReal Alpha_f;
 33:   PetscReal Gamma;
 34:   PetscReal Beta;
 35:   PetscInt  order;

 37:   PetscBool adapt;
 38:   Vec       vec_sol_prev;
 39:   Vec       vec_dot_prev;
 40:   Vec       vec_lte_work[2];

 42:   TSStepStatus status;
 43: } TS_Alpha;

 47: static PetscErrorCode TSAlpha_StageTime(TS ts)
 48: {
 49:   TS_Alpha  *th = (TS_Alpha*)ts->data;
 50:   PetscReal t  = ts->ptime;
 51:   PetscReal dt = ts->time_step;
 52:   PetscReal Alpha_m = th->Alpha_m;
 53:   PetscReal Alpha_f = th->Alpha_f;
 54:   PetscReal Gamma   = th->Gamma;
 55:   PetscReal Beta    = th->Beta;

 58:   th->stage_time = t + Alpha_f*dt;
 59:   th->shift_V = Gamma/(dt*Beta);
 60:   th->shift_A = Alpha_m/(Alpha_f*dt*dt*Beta);
 61:   th->scale_F = 1/Alpha_f;
 62:   return(0);
 63: }

 67: static PetscErrorCode TSAlpha_StageVecs(TS ts,Vec X)
 68: {
 69:   TS_Alpha       *th = (TS_Alpha*)ts->data;
 70:   Vec            X1 = X,      V1 = th->V1, A1 = th->A1;
 71:   Vec            Xa = th->Xa, Va = th->Va, Aa = th->Aa;
 72:   Vec            X0 = th->X0, V0 = th->V0, A0 = th->A0;
 73:   PetscReal      dt = ts->time_step;
 74:   PetscReal      Alpha_m = th->Alpha_m;
 75:   PetscReal      Alpha_f = th->Alpha_f;
 76:   PetscReal      Gamma   = th->Gamma;
 77:   PetscReal      Beta    = th->Beta;

 81:   /* A1 = ... */
 82:   VecWAXPY(A1,-1.0,X0,X1);
 83:   VecAXPY (A1,-dt,V0);
 84:   VecAXPBY(A1,-(1-2*Beta)/(2*Beta),1/(dt*dt*Beta),A0);
 85:   /* V1 = ... */
 86:   VecWAXPY(V1,(1.0-Gamma)/Gamma,A0,A1);
 87:   VecAYPX (V1,dt*Gamma,V0);
 88:   /* Xa = X0 + Alpha_f*(X1-X0) */
 89:   VecWAXPY(Xa,-1.0,X0,X1);
 90:   VecAYPX (Xa,Alpha_f,X0);
 91:   /* Va = V0 + Alpha_f*(V1-V0) */
 92:   VecWAXPY(Va,-1.0,V0,V1);
 93:   VecAYPX (Va,Alpha_f,V0);
 94:   /* Aa = A0 + Alpha_m*(A1-A0) */
 95:   VecWAXPY(Aa,-1.0,A0,A1);
 96:   VecAYPX (Aa,Alpha_m,A0);
 97:   return(0);
 98: }

102: static PetscErrorCode TS_SNESSolve(TS ts,Vec b,Vec x)
103: {
104:   PetscInt       nits,lits;

108:   SNESSolve(ts->snes,b,x);
109:   SNESGetIterationNumber(ts->snes,&nits);
110:   SNESGetLinearSolveIterations(ts->snes,&lits);
111:   ts->snes_its += nits; ts->ksp_its += lits;
112:   return(0);
113: }

115: /*
116:   Compute a consistent initial state for the generalized-alpha method.
117:   - Solve two successive backward Euler steps with halved time step.
118:   - Compute the initial second time derivative using backward differences.
119:   - If using adaptivity, estimate the LTE of the initial step.
120: */
123: static PetscErrorCode TSAlpha_Restart(TS ts,PetscBool *initok)
124: {
125:   TS_Alpha       *th = (TS_Alpha*)ts->data;
126:   PetscReal      time_step;
127:   PetscReal      alpha_m,alpha_f,gamma,beta;
128:   Vec            X0 = ts->vec_sol, X1, X2 = th->X1;
129:   Vec            V0 = ts->vec_dot, V1, V2 = th->V1;
130:   PetscBool      stageok;

134:   VecDuplicate(X0,&X1);
135:   VecDuplicate(V0,&V1);

137:   /* Setup backward Euler with halved time step */
138:   TSAlpha2GetParams(ts,&alpha_m,&alpha_f,&gamma,&beta);
139:   TSAlpha2SetParams(ts,1,1,1,0.5);
140:   TSGetTimeStep(ts,&time_step);
141:   ts->time_step = time_step/2;
142:   TSAlpha_StageTime(ts);
143:   th->stage_time = ts->ptime;
144:   VecZeroEntries(th->A0);

146:   /* First BE step, (t0,X0,V0) -> (t1,X1,V1) */
147:   th->stage_time += ts->time_step;
148:   VecCopy(X0,th->X0);
149:   VecCopy(V0,th->V0);
150:   TSPreStage(ts,th->stage_time);
151:   VecCopy(th->X0,X1);
152:   TS_SNESSolve(ts,NULL,X1);
153:   VecCopy(th->V1,V1);
154:   TSPostStage(ts,th->stage_time,0,&X1);
155:   TSAdaptCheckStage(ts->adapt,ts,th->stage_time,X1,&stageok);
156:   if (!stageok) goto finally;

158:   /* Second BE step, (t1,X1,V1) -> (t2,X2,V2) */
159:   th->stage_time += ts->time_step;
160:   VecCopy(X1,th->X0);
161:   VecCopy(V1,th->V0);
162:   TSPreStage(ts,th->stage_time);
163:   VecCopy(th->X0,X2);
164:   TS_SNESSolve(ts,NULL,X2);
165:   VecCopy(th->V1,V2);
166:   TSPostStage(ts,th->stage_time,0,&X2);
167:   TSAdaptCheckStage(ts->adapt,ts,th->stage_time,X1,&stageok);
168:   if (!stageok) goto finally;

170:   /* Compute A0 ~ dV/dt at t0 with backward differences */
171:   VecZeroEntries(th->A0);
172:   VecAXPY(th->A0,-3/ts->time_step,V0);
173:   VecAXPY(th->A0,+4/ts->time_step,V1);
174:   VecAXPY(th->A0,-1/ts->time_step,V2);

176:   /* Rough, lower-order estimate LTE of the initial step */
177:   if (th->adapt) {
178:     VecZeroEntries(th->vec_lte_work[0]);
179:     VecAXPY(th->vec_lte_work[0],+2,X2);
180:     VecAXPY(th->vec_lte_work[0],-4,X1);
181:     VecAXPY(th->vec_lte_work[0],+2,X0);
182:   }
183:   if (th->adapt) {
184:     VecZeroEntries(th->vec_lte_work[1]);
185:     VecAXPY(th->vec_lte_work[1],+2,V2);
186:     VecAXPY(th->vec_lte_work[1],-4,V1);
187:     VecAXPY(th->vec_lte_work[1],+2,V0);
188:   }

190:  finally:
191:   /* Revert TSAlpha to the initial state (t0,X0,V0) */
192:   if (initok) *initok = stageok;
193:   TSSetTimeStep(ts,time_step);
194:   TSAlpha2SetParams(ts,alpha_m,alpha_f,gamma,beta);
195:   VecCopy(ts->vec_sol,th->X0);
196:   VecCopy(ts->vec_dot,th->V0);

198:   VecDestroy(&X1);
199:   VecDestroy(&V1);
200:   return(0);
201: }

205: static PetscErrorCode TSStep_Alpha(TS ts)
206: {
207:   TS_Alpha       *th = (TS_Alpha*)ts->data;
208:   PetscInt       rejections = 0;
209:   PetscBool      stageok,accept = PETSC_TRUE;
210:   PetscReal      next_time_step = ts->time_step;

214:   PetscCitationsRegister(citation,&cited);

216:   if (!ts->steprollback) {
217:     if (th->adapt) { VecCopy(th->X0,th->vec_sol_prev); }
218:     if (th->adapt) { VecCopy(th->V0,th->vec_dot_prev); }
219:     VecCopy(ts->vec_sol,th->X0);
220:     VecCopy(ts->vec_dot,th->V0);
221:     VecCopy(th->A1,th->A0);
222:   }

224:   th->status = TS_STEP_INCOMPLETE;
225:   while (!ts->reason && th->status != TS_STEP_COMPLETE) {

227:     if (ts->steprestart) {
228:       TSAlpha_Restart(ts,&stageok);
229:       if (!stageok) goto reject_step;
230:     }

232:     TSAlpha_StageTime(ts);
233:     VecCopy(th->X0,th->X1);
234:     TSPreStage(ts,th->stage_time);
235:     TS_SNESSolve(ts,NULL,th->X1);
236:     TSPostStage(ts,th->stage_time,0,&th->Xa);
237:     TSAdaptCheckStage(ts->adapt,ts,th->stage_time,th->Xa,&stageok);
238:     if (!stageok) goto reject_step;

240:     th->status = TS_STEP_PENDING;
241:     VecCopy(th->X1,ts->vec_sol);
242:     VecCopy(th->V1,ts->vec_dot);
243:     TSAdaptChoose(ts->adapt,ts,ts->time_step,NULL,&next_time_step,&accept);
244:     th->status = accept ? TS_STEP_COMPLETE : TS_STEP_INCOMPLETE;
245:     if (!accept) {
246:       VecCopy(th->X0,ts->vec_sol);
247:       VecCopy(th->V0,ts->vec_dot);
248:       ts->time_step = next_time_step;
249:       goto reject_step;
250:     }

252:     ts->ptime += ts->time_step;
253:     ts->time_step = next_time_step;
254:     break;

256:   reject_step:
257:     ts->reject++; accept = PETSC_FALSE;
258:     if (!ts->reason && ++rejections > ts->max_reject && ts->max_reject >= 0) {
259:       ts->reason = TS_DIVERGED_STEP_REJECTED;
260:       PetscInfo2(ts,"Step=%D, step rejections %D greater than current TS allowed, stopping solve\n",ts->steps,rejections);
261:     }

263:   }
264:   return(0);
265: }

269: static PetscErrorCode TSEvaluateWLTE_Alpha(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte)
270: {
271:   TS_Alpha       *th = (TS_Alpha*)ts->data;
272:   Vec            X = th->X1;              /* X = solution */
273:   Vec            V = th->V1;              /* V = solution */
274:   Vec            Y = th->vec_lte_work[0]; /* Y = X + LTE  */
275:   Vec            Z = th->vec_lte_work[1]; /* Z = V + LTE  */
276:   PetscReal      enormX,enormV;

280:   if (ts->steprestart) {
281:     /* th->vec_{sol|dot}_prev is set to the LTE in TSAlpha_Restart() */
282:     VecAXPY(Y,1,X);
283:     VecAXPY(Z,1,V);
284:   } else {
285:     /* Compute LTE using backward differences with non-constant time step */
286:     PetscReal   h = ts->time_step, h_prev = ts->ptime - ts->ptime_prev;
287:     PetscReal   a = 1 + h_prev/h;
288:     PetscScalar scal[3]; Vec vecX[3],vecV[3];
289:     scal[0] = +1/a;   scal[1] = -1/(a-1); scal[2] = +1/(a*(a-1));
290:     vecX[0] = th->X1; vecX[1] = th->X0;   vecX[2] = th->vec_sol_prev;
291:     vecV[0] = th->V1; vecV[1] = th->V0;   vecV[2] = th->vec_dot_prev;
292:     VecCopy(X,Y);
293:     VecMAXPY(Y,3,scal,vecX);
294:     VecCopy(V,Z);
295:     VecMAXPY(Z,3,scal,vecV);
296:   }
297:   /* XXX ts->atol and ts->vatol are not appropriate for computing enormV */
298:   TSErrorWeightedNorm(ts,X,Y,wnormtype,&enormX);
299:   TSErrorWeightedNorm(ts,V,Z,wnormtype,&enormV);
300:   if (wnormtype == NORM_2)
301:     *wlte = PetscSqrtReal(PetscSqr(enormX)/2 + PetscSqr(enormV)/2);
302:   else
303:     *wlte = PetscMax(enormX,enormV);
304:   if (order) *order = 2;
305:   return(0);
306: }

310: static PetscErrorCode TSRollBack_Alpha(TS ts)
311: {
312:   TS_Alpha       *th = (TS_Alpha*)ts->data;

316:   VecCopy(th->X0,ts->vec_sol);
317:   VecCopy(th->V0,ts->vec_dot);
318:   return(0);
319: }

321: /*
324: static PetscErrorCode TSInterpolate_Alpha(TS ts,PetscReal t,Vec X,Vec V)
325: {
326:   TS_Alpha       *th = (TS_Alpha*)ts->data;
327:   PetscReal      dt  = t - ts->ptime;

331:   VecCopy(ts->vec_dot,V);
332:   VecAXPY(V,dt*(1-th->Gamma),th->A0);
333:   VecAXPY(V,dt*th->Gamma,th->A1);
334:   VecCopy(ts->vec_sol,X);
335:   VecAXPY(X,dt,V);
336:   VecAXPY(X,dt*dt*((PetscReal)0.5-th->Beta),th->A0);
337:   VecAXPY(X,dt*dt*th->Beta,th->A1);
338:   return(0);
339: }
340: */

344: static PetscErrorCode SNESTSFormFunction_Alpha(PETSC_UNUSED SNES snes,Vec X,Vec F,TS ts)
345: {
346:   TS_Alpha       *th = (TS_Alpha*)ts->data;
347:   PetscReal      ta = th->stage_time;
348:   Vec            Xa = th->Xa, Va = th->Va, Aa = th->Aa;

352:   TSAlpha_StageVecs(ts,X);
353:   /* F = Function(ta,Xa,Va,Aa) */
354:   TSComputeI2Function(ts,ta,Xa,Va,Aa,F);
355:   VecScale(F,th->scale_F);
356:   return(0);
357: }

361: static PetscErrorCode SNESTSFormJacobian_Alpha(PETSC_UNUSED SNES snes,PETSC_UNUSED Vec X,Mat J,Mat P,TS ts)
362: {
363:   TS_Alpha       *th = (TS_Alpha*)ts->data;
364:   PetscReal      ta = th->stage_time;
365:   Vec            Xa = th->Xa, Va = th->Va, Aa = th->Aa;
366:   PetscReal      dVdX = th->shift_V, dAdX = th->shift_A;

370:   /* J,P = Jacobian(ta,Xa,Va,Aa) */
371:   TSComputeI2Jacobian(ts,ta,Xa,Va,Aa,dVdX,dAdX,J,P);
372:   return(0);
373: }

377: static PetscErrorCode TSReset_Alpha(TS ts)
378: {
379:   TS_Alpha       *th = (TS_Alpha*)ts->data;

383:   VecDestroy(&th->X0);
384:   VecDestroy(&th->Xa);
385:   VecDestroy(&th->X1);
386:   VecDestroy(&th->V0);
387:   VecDestroy(&th->Va);
388:   VecDestroy(&th->V1);
389:   VecDestroy(&th->A0);
390:   VecDestroy(&th->Aa);
391:   VecDestroy(&th->A1);
392:   VecDestroy(&th->vec_sol_prev);
393:   VecDestroy(&th->vec_dot_prev);
394:   VecDestroy(&th->vec_lte_work[0]);
395:   VecDestroy(&th->vec_lte_work[1]);
396:   return(0);
397: }

401: static PetscErrorCode TSDestroy_Alpha(TS ts)
402: {

406:   TSReset_Alpha(ts);
407:   PetscFree(ts->data);

409:   PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2UseAdapt_C",NULL);
410:   PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2SetRadius_C",NULL);
411:   PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2SetParams_C",NULL);
412:   PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2GetParams_C",NULL);
413:   return(0);
414: }

418: static PetscErrorCode TSSetUp_Alpha(TS ts)
419: {
420:   TS_Alpha       *th = (TS_Alpha*)ts->data;

424:   VecDuplicate(ts->vec_sol,&th->X0);
425:   VecDuplicate(ts->vec_sol,&th->Xa);
426:   VecDuplicate(ts->vec_sol,&th->X1);
427:   VecDuplicate(ts->vec_sol,&th->V0);
428:   VecDuplicate(ts->vec_sol,&th->Va);
429:   VecDuplicate(ts->vec_sol,&th->V1);
430:   VecDuplicate(ts->vec_sol,&th->A0);
431:   VecDuplicate(ts->vec_sol,&th->Aa);
432:   VecDuplicate(ts->vec_sol,&th->A1);

434:   TSGetAdapt(ts,&ts->adapt);
435:   TSAdaptCandidatesClear(ts->adapt);
436:   if (!th->adapt) {
437:     TSAdaptSetType(ts->adapt,TSADAPTNONE);
438:   } else {
439:     VecDuplicate(ts->vec_sol,&th->vec_sol_prev);
440:     VecDuplicate(ts->vec_sol,&th->vec_dot_prev);
441:     VecDuplicate(ts->vec_sol,&th->vec_lte_work[0]);
442:     VecDuplicate(ts->vec_sol,&th->vec_lte_work[1]);
443:     if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED)
444:       ts->exact_final_time = TS_EXACTFINALTIME_MATCHSTEP;
445:   }

447:   TSGetSNES(ts,&ts->snes);
448:   return(0);
449: }

453: static PetscErrorCode TSSetFromOptions_Alpha(PetscOptionItems *PetscOptionsObject,TS ts)
454: {
455:   TS_Alpha       *th = (TS_Alpha*)ts->data;

459:   PetscOptionsHead(PetscOptionsObject,"Generalized-Alpha ODE solver options");
460:   {
461:     PetscBool flg;
462:     PetscReal radius = 1;
463:     PetscBool adapt  = th->adapt;
464:     PetscOptionsReal("-ts_alpha_radius","Spectral radius (high-frequency dissipation)","TSAlpha2SetRadius",radius,&radius,&flg);
465:     if (flg) {TSAlpha2SetRadius(ts,radius);}
466:     PetscOptionsReal("-ts_alpha_alpha_m","Algoritmic parameter alpha_m","TSAlpha2SetParams",th->Alpha_m,&th->Alpha_m,NULL);
467:     PetscOptionsReal("-ts_alpha_alpha_f","Algoritmic parameter alpha_f","TSAlpha2SetParams",th->Alpha_f,&th->Alpha_f,NULL);
468:     PetscOptionsReal("-ts_alpha_gamma","Algoritmic parameter gamma","TSAlpha2SetParams",th->Gamma,&th->Gamma,NULL);
469:     PetscOptionsReal("-ts_alpha_beta","Algoritmic parameter beta","TSAlpha2SetParams",th->Beta,&th->Beta,NULL);
470:     TSAlpha2SetParams(ts,th->Alpha_m,th->Alpha_f,th->Gamma,th->Beta);
471:     PetscOptionsBool("-ts_alpha_adapt","Use time-step adaptivity with the Alpha method","TSAlpha2UseAdapt",adapt,&adapt,&flg);
472:     if (flg) {TSAlpha2UseAdapt(ts,adapt);}
473:   }
474:   PetscOptionsTail();
475:   return(0);
476: }

480: static PetscErrorCode TSView_Alpha(TS ts,PetscViewer viewer)
481: {
482:   TS_Alpha       *th = (TS_Alpha*)ts->data;
483:   PetscBool      iascii;

487:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
488:   if (iascii) {
489:     PetscViewerASCIIPrintf(viewer,"  Alpha_m=%g, Alpha_f=%g, Gamma=%g, Beta=%g\n",(double)th->Alpha_m,(double)th->Alpha_f,(double)th->Gamma,(double)th->Beta);
490:   }
491:   if (ts->adapt) {TSAdaptView(ts->adapt,viewer);}
492:   if (ts->snes)  {SNESView(ts->snes,viewer);}
493:   return(0);
494: }

498: static PetscErrorCode TSAlpha2UseAdapt_Alpha(TS ts,PetscBool use)
499: {
500:   TS_Alpha *th = (TS_Alpha*)ts->data;

503:   if (use == th->adapt) return(0);
504:   if (ts->setupcalled) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ORDER,"Cannot change adaptivity after TSSetUp()");
505:   th->adapt = use;
506:   return(0);
507: }

511: static PetscErrorCode TSAlpha2SetRadius_Alpha(TS ts,PetscReal radius)
512: {
513:   PetscReal      alpha_m,alpha_f,gamma,beta;

517:   if (radius < 0 || radius > 1) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Radius %g not in range [0,1]",(double)radius);
518:   alpha_m = (2-radius)/(1+radius);
519:   alpha_f = 1/(1+radius);
520:   gamma   = (PetscReal)0.5 + alpha_m - alpha_f;
521:   beta    = (PetscReal)0.5 * (1 + alpha_m - alpha_f); beta *= beta;
522:   TSAlpha2SetParams(ts,alpha_m,alpha_f,gamma,beta);
523:   return(0);
524: }

528: static PetscErrorCode TSAlpha2SetParams_Alpha(TS ts,PetscReal alpha_m,PetscReal alpha_f,PetscReal gamma,PetscReal beta)
529: {
530:   TS_Alpha  *th = (TS_Alpha*)ts->data;
531:   PetscReal tol = 100*PETSC_MACHINE_EPSILON;
532:   PetscReal res = ((PetscReal)0.5 + alpha_m - alpha_f) - gamma;

535:   th->Alpha_m = alpha_m;
536:   th->Alpha_f = alpha_f;
537:   th->Gamma   = gamma;
538:   th->Beta    = beta;
539:   th->order   = (PetscAbsReal(res) < tol) ? 2 : 1;
540:   return(0);
541: }

545: static PetscErrorCode TSAlpha2GetParams_Alpha(TS ts,PetscReal *alpha_m,PetscReal *alpha_f,PetscReal *gamma,PetscReal *beta)
546: {
547:   TS_Alpha *th = (TS_Alpha*)ts->data;

550:   if (alpha_m) *alpha_m = th->Alpha_m;
551:   if (alpha_f) *alpha_f = th->Alpha_f;
552:   if (gamma)   *gamma   = th->Gamma;
553:   if (beta)    *beta    = th->Beta;
554:   return(0);
555: }

557: /*MC
558:       TSALPHA2 - ODE/DAE solver using the implicit Generalized-Alpha method
559:                  for second-order systems

561:   Level: beginner

563:   References:
564:   J. Chung, G.M.Hubert. "A Time Integration Algorithm for Structural
565:   Dynamics with Improved Numerical Dissipation: The Generalized-alpha
566:   Method" ASME Journal of Applied Mechanics, 60, 371:375, 1993.

568: .seealso:  TS, TSCreate(), TSSetType(), TSAlpha2SetRadius(), TSAlpha2SetParams()
569: M*/
572: PETSC_EXTERN PetscErrorCode TSCreate_Alpha2(TS ts)
573: {
574:   TS_Alpha       *th;

578:   ts->ops->reset          = TSReset_Alpha;
579:   ts->ops->destroy        = TSDestroy_Alpha;
580:   ts->ops->view           = TSView_Alpha;
581:   ts->ops->setup          = TSSetUp_Alpha;
582:   ts->ops->setfromoptions = TSSetFromOptions_Alpha;
583:   ts->ops->step           = TSStep_Alpha;
584:   ts->ops->evaluatewlte   = TSEvaluateWLTE_Alpha;
585:   ts->ops->rollback       = TSRollBack_Alpha;
586:   /*ts->ops->interpolate  = TSInterpolate_Alpha;*/
587:   ts->ops->snesfunction   = SNESTSFormFunction_Alpha;
588:   ts->ops->snesjacobian   = SNESTSFormJacobian_Alpha;

590:   PetscNewLog(ts,&th);
591:   ts->data = (void*)th;

593:   th->Alpha_m = 0.5;
594:   th->Alpha_f = 0.5;
595:   th->Gamma   = 0.5;
596:   th->Beta    = 0.25;
597:   th->order   = 2;

599:   th->adapt = PETSC_FALSE;

601:   PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2UseAdapt_C",TSAlpha2UseAdapt_Alpha);
602:   PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2SetRadius_C",TSAlpha2SetRadius_Alpha);
603:   PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2SetParams_C",TSAlpha2SetParams_Alpha);
604:   PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2GetParams_C",TSAlpha2GetParams_Alpha);
605:   return(0);
606: }

610: /*@
611:   TSAlpha2UseAdapt - Use time-step adaptivity with the Alpha method

613:   Logically Collective on TS

615:   Input Parameter:
616: +  ts - timestepping context
617: -  use - flag to use adaptivity

619:   Options Database:
620: .  -ts_alpha_adapt

622:   Level: intermediate

624: .seealso: TSAdapt, TSADAPTBASIC
625: @*/
626: PetscErrorCode TSAlpha2UseAdapt(TS ts,PetscBool use)
627: {

633:   PetscTryMethod(ts,"TSAlpha2UseAdapt_C",(TS,PetscBool),(ts,use));
634:   return(0);
635: }

639: /*@
640:   TSAlpha2SetRadius - sets the desired spectral radius of the method
641:                       (i.e. high-frequency numerical damping)

643:   Logically Collective on TS

645:   The algorithmic parameters \alpha_m and \alpha_f of the
646:   generalized-\alpha method can be computed in terms of a specified
647:   spectral radius \rho in [0,1] for infinite time step in order to
648:   control high-frequency numerical damping:
649:     \alpha_m = (2-\rho)/(1+\rho)
650:     \alpha_f = 1/(1+\rho)

652:   Input Parameter:
653: +  ts - timestepping context
654: -  radius - the desired spectral radius

656:   Options Database:
657: .  -ts_alpha_radius <radius>

659:   Level: intermediate

661: .seealso: TSAlpha2SetParams(), TSAlpha2GetParams()
662: @*/
663: PetscErrorCode TSAlpha2SetRadius(TS ts,PetscReal radius)
664: {

670:   if (radius < 0 || radius > 1) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Radius %g not in range [0,1]",(double)radius);
671:   PetscTryMethod(ts,"TSAlpha2SetRadius_C",(TS,PetscReal),(ts,radius));
672:   return(0);
673: }

677: /*@
678:   TSAlpha2SetParams - sets the algorithmic parameters for TSALPHA2

680:   Logically Collective on TS

682:   Second-order accuracy can be obtained so long as:
683:     \gamma = 1/2 + alpha_m - alpha_f
684:     \beta  = 1/4 (1 + alpha_m - alpha_f)^2

686:   Unconditional stability requires:
687:     \alpha_m >= \alpha_f >= 1/2


690:   Input Parameter:
691: + ts - timestepping context
692: . \alpha_m - algorithmic paramenter
693: . \alpha_f - algorithmic paramenter
694: . \gamma   - algorithmic paramenter
695: - \beta    - algorithmic paramenter

697:   Options Database:
698: + -ts_alpha_alpha_m <alpha_m>
699: . -ts_alpha_alpha_f <alpha_f>
700: . -ts_alpha_gamma   <gamma>
701: - -ts_alpha_beta    <beta>

703:   Note:
704:   Use of this function is normally only required to hack TSALPHA2 to
705:   use a modified integration scheme. Users should call
706:   TSAlpha2SetRadius() to set the desired spectral radius of the methods
707:   (i.e. high-frequency damping) in order so select optimal values for
708:   these parameters.

710:   Level: advanced

712: .seealso: TSAlpha2SetRadius(), TSAlpha2GetParams()
713: @*/
714: PetscErrorCode TSAlpha2SetParams(TS ts,PetscReal alpha_m,PetscReal alpha_f,PetscReal gamma,PetscReal beta)
715: {

724:   PetscTryMethod(ts,"TSAlpha2SetParams_C",(TS,PetscReal,PetscReal,PetscReal,PetscReal),(ts,alpha_m,alpha_f,gamma,beta));
725:   return(0);
726: }

730: /*@
731:   TSAlpha2GetParams - gets the algorithmic parameters for TSALPHA2

733:   Not Collective

735:   Input Parameter:
736: . ts - timestepping context

738:   Output Parameters:
739: + \alpha_m - algorithmic parameter
740: . \alpha_f - algorithmic parameter
741: . \gamma   - algorithmic parameter
742: - \beta    - algorithmic parameter

744:   Note:
745:   Use of this function is normally only required to hack TSALPHA2 to
746:   use a modified integration scheme. Users should call
747:   TSAlpha2SetRadius() to set the high-frequency damping (i.e. spectral
748:   radius of the method) in order so select optimal values for these
749:   parameters.

751:   Level: advanced

753: .seealso: TSAlpha2SetRadius(), TSAlpha2SetParams()
754: @*/
755: PetscErrorCode TSAlpha2GetParams(TS ts,PetscReal *alpha_m,PetscReal *alpha_f,PetscReal *gamma,PetscReal *beta)
756: {

765:   PetscUseMethod(ts,"TSAlpha2GetParams_C",(TS,PetscReal*,PetscReal*,PetscReal*,PetscReal*),(ts,alpha_m,alpha_f,gamma,beta));
766:   return(0);
767: }