Actual source code: alpha2.c
petsc-3.13.6 2020-09-29
1: /*
2: Code for timestepping with implicit generalized-\alpha method
3: for second order systems.
4: */
5: #include <petsc/private/tsimpl.h>
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: Vec vec_sol_prev;
38: Vec vec_dot_prev;
39: Vec vec_lte_work[2];
41: TSStepStatus status;
42: } TS_Alpha;
44: static PetscErrorCode TSAlpha_StageTime(TS ts)
45: {
46: TS_Alpha *th = (TS_Alpha*)ts->data;
47: PetscReal t = ts->ptime;
48: PetscReal dt = ts->time_step;
49: PetscReal Alpha_m = th->Alpha_m;
50: PetscReal Alpha_f = th->Alpha_f;
51: PetscReal Gamma = th->Gamma;
52: PetscReal Beta = th->Beta;
55: th->stage_time = t + Alpha_f*dt;
56: th->shift_V = Gamma/(dt*Beta);
57: th->shift_A = Alpha_m/(Alpha_f*dt*dt*Beta);
58: th->scale_F = 1/Alpha_f;
59: return(0);
60: }
62: static PetscErrorCode TSAlpha_StageVecs(TS ts,Vec X)
63: {
64: TS_Alpha *th = (TS_Alpha*)ts->data;
65: Vec X1 = X, V1 = th->V1, A1 = th->A1;
66: Vec Xa = th->Xa, Va = th->Va, Aa = th->Aa;
67: Vec X0 = th->X0, V0 = th->V0, A0 = th->A0;
68: PetscReal dt = ts->time_step;
69: PetscReal Alpha_m = th->Alpha_m;
70: PetscReal Alpha_f = th->Alpha_f;
71: PetscReal Gamma = th->Gamma;
72: PetscReal Beta = th->Beta;
76: /* A1 = ... */
77: VecWAXPY(A1,-1.0,X0,X1);
78: VecAXPY (A1,-dt,V0);
79: VecAXPBY(A1,-(1-2*Beta)/(2*Beta),1/(dt*dt*Beta),A0);
80: /* V1 = ... */
81: VecWAXPY(V1,(1.0-Gamma)/Gamma,A0,A1);
82: VecAYPX (V1,dt*Gamma,V0);
83: /* Xa = X0 + Alpha_f*(X1-X0) */
84: VecWAXPY(Xa,-1.0,X0,X1);
85: VecAYPX (Xa,Alpha_f,X0);
86: /* Va = V0 + Alpha_f*(V1-V0) */
87: VecWAXPY(Va,-1.0,V0,V1);
88: VecAYPX (Va,Alpha_f,V0);
89: /* Aa = A0 + Alpha_m*(A1-A0) */
90: VecWAXPY(Aa,-1.0,A0,A1);
91: VecAYPX (Aa,Alpha_m,A0);
92: return(0);
93: }
95: static PetscErrorCode TSAlpha_SNESSolve(TS ts,Vec b,Vec x)
96: {
97: PetscInt nits,lits;
101: SNESSolve(ts->snes,b,x);
102: SNESGetIterationNumber(ts->snes,&nits);
103: SNESGetLinearSolveIterations(ts->snes,&lits);
104: ts->snes_its += nits; ts->ksp_its += lits;
105: return(0);
106: }
108: /*
109: Compute a consistent initial state for the generalized-alpha method.
110: - Solve two successive backward Euler steps with halved time step.
111: - Compute the initial second time derivative using backward differences.
112: - If using adaptivity, estimate the LTE of the initial step.
113: */
114: static PetscErrorCode TSAlpha_Restart(TS ts,PetscBool *initok)
115: {
116: TS_Alpha *th = (TS_Alpha*)ts->data;
117: PetscReal time_step;
118: PetscReal alpha_m,alpha_f,gamma,beta;
119: Vec X0 = ts->vec_sol, X1, X2 = th->X1;
120: Vec V0 = ts->vec_dot, V1, V2 = th->V1;
121: PetscBool stageok;
125: VecDuplicate(X0,&X1);
126: VecDuplicate(V0,&V1);
128: /* Setup backward Euler with halved time step */
129: TSAlpha2GetParams(ts,&alpha_m,&alpha_f,&gamma,&beta);
130: TSAlpha2SetParams(ts,1,1,1,0.5);
131: TSGetTimeStep(ts,&time_step);
132: ts->time_step = time_step/2;
133: TSAlpha_StageTime(ts);
134: th->stage_time = ts->ptime;
135: VecZeroEntries(th->A0);
137: /* First BE step, (t0,X0,V0) -> (t1,X1,V1) */
138: th->stage_time += ts->time_step;
139: VecCopy(X0,th->X0);
140: VecCopy(V0,th->V0);
141: TSPreStage(ts,th->stage_time);
142: VecCopy(th->X0,X1);
143: TSAlpha_SNESSolve(ts,NULL,X1);
144: VecCopy(th->V1,V1);
145: TSPostStage(ts,th->stage_time,0,&X1);
146: TSAdaptCheckStage(ts->adapt,ts,th->stage_time,X1,&stageok);
147: if (!stageok) goto finally;
149: /* Second BE step, (t1,X1,V1) -> (t2,X2,V2) */
150: th->stage_time += ts->time_step;
151: VecCopy(X1,th->X0);
152: VecCopy(V1,th->V0);
153: TSPreStage(ts,th->stage_time);
154: VecCopy(th->X0,X2);
155: TSAlpha_SNESSolve(ts,NULL,X2);
156: VecCopy(th->V1,V2);
157: TSPostStage(ts,th->stage_time,0,&X2);
158: TSAdaptCheckStage(ts->adapt,ts,th->stage_time,X1,&stageok);
159: if (!stageok) goto finally;
161: /* Compute A0 ~ dV/dt at t0 with backward differences */
162: VecZeroEntries(th->A0);
163: VecAXPY(th->A0,-3/ts->time_step,V0);
164: VecAXPY(th->A0,+4/ts->time_step,V1);
165: VecAXPY(th->A0,-1/ts->time_step,V2);
167: /* Rough, lower-order estimate LTE of the initial step */
168: if (th->vec_lte_work[0]) {
169: VecZeroEntries(th->vec_lte_work[0]);
170: VecAXPY(th->vec_lte_work[0],+2,X2);
171: VecAXPY(th->vec_lte_work[0],-4,X1);
172: VecAXPY(th->vec_lte_work[0],+2,X0);
173: }
174: if (th->vec_lte_work[1]) {
175: VecZeroEntries(th->vec_lte_work[1]);
176: VecAXPY(th->vec_lte_work[1],+2,V2);
177: VecAXPY(th->vec_lte_work[1],-4,V1);
178: VecAXPY(th->vec_lte_work[1],+2,V0);
179: }
181: finally:
182: /* Revert TSAlpha to the initial state (t0,X0,V0) */
183: if (initok) *initok = stageok;
184: TSSetTimeStep(ts,time_step);
185: TSAlpha2SetParams(ts,alpha_m,alpha_f,gamma,beta);
186: VecCopy(ts->vec_sol,th->X0);
187: VecCopy(ts->vec_dot,th->V0);
189: VecDestroy(&X1);
190: VecDestroy(&V1);
191: return(0);
192: }
194: static PetscErrorCode TSStep_Alpha(TS ts)
195: {
196: TS_Alpha *th = (TS_Alpha*)ts->data;
197: PetscInt rejections = 0;
198: PetscBool stageok,accept = PETSC_TRUE;
199: PetscReal next_time_step = ts->time_step;
203: PetscCitationsRegister(citation,&cited);
205: if (!ts->steprollback) {
206: if (th->vec_sol_prev) { VecCopy(th->X0,th->vec_sol_prev); }
207: if (th->vec_dot_prev) { VecCopy(th->V0,th->vec_dot_prev); }
208: VecCopy(ts->vec_sol,th->X0);
209: VecCopy(ts->vec_dot,th->V0);
210: VecCopy(th->A1,th->A0);
211: }
213: th->status = TS_STEP_INCOMPLETE;
214: while (!ts->reason && th->status != TS_STEP_COMPLETE) {
216: if (ts->steprestart) {
217: TSAlpha_Restart(ts,&stageok);
218: if (!stageok) goto reject_step;
219: }
221: TSAlpha_StageTime(ts);
222: VecCopy(th->X0,th->X1);
223: TSPreStage(ts,th->stage_time);
224: TSAlpha_SNESSolve(ts,NULL,th->X1);
225: TSPostStage(ts,th->stage_time,0,&th->Xa);
226: TSAdaptCheckStage(ts->adapt,ts,th->stage_time,th->Xa,&stageok);
227: if (!stageok) goto reject_step;
229: th->status = TS_STEP_PENDING;
230: VecCopy(th->X1,ts->vec_sol);
231: VecCopy(th->V1,ts->vec_dot);
232: TSAdaptChoose(ts->adapt,ts,ts->time_step,NULL,&next_time_step,&accept);
233: th->status = accept ? TS_STEP_COMPLETE : TS_STEP_INCOMPLETE;
234: if (!accept) {
235: VecCopy(th->X0,ts->vec_sol);
236: VecCopy(th->V0,ts->vec_dot);
237: ts->time_step = next_time_step;
238: goto reject_step;
239: }
241: ts->ptime += ts->time_step;
242: ts->time_step = next_time_step;
243: break;
245: reject_step:
246: ts->reject++; accept = PETSC_FALSE;
247: if (!ts->reason && ++rejections > ts->max_reject && ts->max_reject >= 0) {
248: ts->reason = TS_DIVERGED_STEP_REJECTED;
249: PetscInfo2(ts,"Step=%D, step rejections %D greater than current TS allowed, stopping solve\n",ts->steps,rejections);
250: }
252: }
253: return(0);
254: }
256: static PetscErrorCode TSEvaluateWLTE_Alpha(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte)
257: {
258: TS_Alpha *th = (TS_Alpha*)ts->data;
259: Vec X = th->X1; /* X = solution */
260: Vec V = th->V1; /* V = solution */
261: Vec Y = th->vec_lte_work[0]; /* Y = X + LTE */
262: Vec Z = th->vec_lte_work[1]; /* Z = V + LTE */
263: PetscReal enormX,enormV,enormXa,enormVa,enormXr,enormVr;
267: if (!th->vec_sol_prev) {*wlte = -1; return(0);}
268: if (!th->vec_dot_prev) {*wlte = -1; return(0);}
269: if (!th->vec_lte_work[0]) {*wlte = -1; return(0);}
270: if (!th->vec_lte_work[1]) {*wlte = -1; return(0);}
271: if (ts->steprestart) {
272: /* th->vec_lte_prev is set to the LTE in TSAlpha_Restart() */
273: VecAXPY(Y,1,X);
274: VecAXPY(Z,1,V);
275: } else {
276: /* Compute LTE using backward differences with non-constant time step */
277: PetscReal h = ts->time_step, h_prev = ts->ptime - ts->ptime_prev;
278: PetscReal a = 1 + h_prev/h;
279: PetscScalar scal[3]; Vec vecX[3],vecV[3];
280: scal[0] = +1/a; scal[1] = -1/(a-1); scal[2] = +1/(a*(a-1));
281: vecX[0] = th->X1; vecX[1] = th->X0; vecX[2] = th->vec_sol_prev;
282: vecV[0] = th->V1; vecV[1] = th->V0; vecV[2] = th->vec_dot_prev;
283: VecCopy(X,Y);
284: VecMAXPY(Y,3,scal,vecX);
285: VecCopy(V,Z);
286: VecMAXPY(Z,3,scal,vecV);
287: }
288: /* XXX ts->atol and ts->vatol are not appropriate for computing enormV */
289: TSErrorWeightedNorm(ts,X,Y,wnormtype,&enormX,&enormXa,&enormXr);
290: TSErrorWeightedNorm(ts,V,Z,wnormtype,&enormV,&enormVa,&enormVr);
291: if (wnormtype == NORM_2)
292: *wlte = PetscSqrtReal(PetscSqr(enormX)/2 + PetscSqr(enormV)/2);
293: else
294: *wlte = PetscMax(enormX,enormV);
295: if (order) *order = 2;
296: return(0);
297: }
299: static PetscErrorCode TSRollBack_Alpha(TS ts)
300: {
301: TS_Alpha *th = (TS_Alpha*)ts->data;
305: VecCopy(th->X0,ts->vec_sol);
306: VecCopy(th->V0,ts->vec_dot);
307: return(0);
308: }
310: /*
311: static PetscErrorCode TSInterpolate_Alpha(TS ts,PetscReal t,Vec X,Vec V)
312: {
313: TS_Alpha *th = (TS_Alpha*)ts->data;
314: PetscReal dt = t - ts->ptime;
318: VecCopy(ts->vec_dot,V);
319: VecAXPY(V,dt*(1-th->Gamma),th->A0);
320: VecAXPY(V,dt*th->Gamma,th->A1);
321: VecCopy(ts->vec_sol,X);
322: VecAXPY(X,dt,V);
323: VecAXPY(X,dt*dt*((PetscReal)0.5-th->Beta),th->A0);
324: VecAXPY(X,dt*dt*th->Beta,th->A1);
325: return(0);
326: }
327: */
329: static PetscErrorCode SNESTSFormFunction_Alpha(PETSC_UNUSED SNES snes,Vec X,Vec F,TS ts)
330: {
331: TS_Alpha *th = (TS_Alpha*)ts->data;
332: PetscReal ta = th->stage_time;
333: Vec Xa = th->Xa, Va = th->Va, Aa = th->Aa;
337: TSAlpha_StageVecs(ts,X);
338: /* F = Function(ta,Xa,Va,Aa) */
339: TSComputeI2Function(ts,ta,Xa,Va,Aa,F);
340: VecScale(F,th->scale_F);
341: return(0);
342: }
344: static PetscErrorCode SNESTSFormJacobian_Alpha(PETSC_UNUSED SNES snes,PETSC_UNUSED Vec X,Mat J,Mat P,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;
349: PetscReal dVdX = th->shift_V, dAdX = th->shift_A;
353: /* J,P = Jacobian(ta,Xa,Va,Aa) */
354: TSComputeI2Jacobian(ts,ta,Xa,Va,Aa,dVdX,dAdX,J,P);
355: return(0);
356: }
358: static PetscErrorCode TSReset_Alpha(TS ts)
359: {
360: TS_Alpha *th = (TS_Alpha*)ts->data;
364: VecDestroy(&th->X0);
365: VecDestroy(&th->Xa);
366: VecDestroy(&th->X1);
367: VecDestroy(&th->V0);
368: VecDestroy(&th->Va);
369: VecDestroy(&th->V1);
370: VecDestroy(&th->A0);
371: VecDestroy(&th->Aa);
372: VecDestroy(&th->A1);
373: VecDestroy(&th->vec_sol_prev);
374: VecDestroy(&th->vec_dot_prev);
375: VecDestroy(&th->vec_lte_work[0]);
376: VecDestroy(&th->vec_lte_work[1]);
377: return(0);
378: }
380: static PetscErrorCode TSDestroy_Alpha(TS ts)
381: {
385: TSReset_Alpha(ts);
386: PetscFree(ts->data);
388: PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2SetRadius_C",NULL);
389: PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2SetParams_C",NULL);
390: PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2GetParams_C",NULL);
391: return(0);
392: }
394: static PetscErrorCode TSSetUp_Alpha(TS ts)
395: {
396: TS_Alpha *th = (TS_Alpha*)ts->data;
397: PetscBool match;
401: VecDuplicate(ts->vec_sol,&th->X0);
402: VecDuplicate(ts->vec_sol,&th->Xa);
403: VecDuplicate(ts->vec_sol,&th->X1);
404: VecDuplicate(ts->vec_sol,&th->V0);
405: VecDuplicate(ts->vec_sol,&th->Va);
406: VecDuplicate(ts->vec_sol,&th->V1);
407: VecDuplicate(ts->vec_sol,&th->A0);
408: VecDuplicate(ts->vec_sol,&th->Aa);
409: VecDuplicate(ts->vec_sol,&th->A1);
411: TSGetAdapt(ts,&ts->adapt);
412: TSAdaptCandidatesClear(ts->adapt);
413: PetscObjectTypeCompare((PetscObject)ts->adapt,TSADAPTNONE,&match);
414: if (!match) {
415: VecDuplicate(ts->vec_sol,&th->vec_sol_prev);
416: VecDuplicate(ts->vec_sol,&th->vec_dot_prev);
417: VecDuplicate(ts->vec_sol,&th->vec_lte_work[0]);
418: VecDuplicate(ts->vec_sol,&th->vec_lte_work[1]);
419: }
421: TSGetSNES(ts,&ts->snes);
422: return(0);
423: }
425: static PetscErrorCode TSSetFromOptions_Alpha(PetscOptionItems *PetscOptionsObject,TS ts)
426: {
427: TS_Alpha *th = (TS_Alpha*)ts->data;
431: PetscOptionsHead(PetscOptionsObject,"Generalized-Alpha ODE solver options");
432: {
433: PetscBool flg;
434: PetscReal radius = 1;
435: PetscOptionsReal("-ts_alpha_radius","Spectral radius (high-frequency dissipation)","TSAlpha2SetRadius",radius,&radius,&flg);
436: if (flg) {TSAlpha2SetRadius(ts,radius);}
437: PetscOptionsReal("-ts_alpha_alpha_m","Algorithmic parameter alpha_m","TSAlpha2SetParams",th->Alpha_m,&th->Alpha_m,NULL);
438: PetscOptionsReal("-ts_alpha_alpha_f","Algorithmic parameter alpha_f","TSAlpha2SetParams",th->Alpha_f,&th->Alpha_f,NULL);
439: PetscOptionsReal("-ts_alpha_gamma","Algorithmic parameter gamma","TSAlpha2SetParams",th->Gamma,&th->Gamma,NULL);
440: PetscOptionsReal("-ts_alpha_beta","Algorithmic parameter beta","TSAlpha2SetParams",th->Beta,&th->Beta,NULL);
441: TSAlpha2SetParams(ts,th->Alpha_m,th->Alpha_f,th->Gamma,th->Beta);
442: }
443: PetscOptionsTail();
444: return(0);
445: }
447: static PetscErrorCode TSView_Alpha(TS ts,PetscViewer viewer)
448: {
449: TS_Alpha *th = (TS_Alpha*)ts->data;
450: PetscBool iascii;
454: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
455: if (iascii) {
456: 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);
457: }
458: return(0);
459: }
461: static PetscErrorCode TSAlpha2SetRadius_Alpha(TS ts,PetscReal radius)
462: {
463: PetscReal alpha_m,alpha_f,gamma,beta;
467: if (radius < 0 || radius > 1) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Radius %g not in range [0,1]",(double)radius);
468: alpha_m = (2-radius)/(1+radius);
469: alpha_f = 1/(1+radius);
470: gamma = (PetscReal)0.5 + alpha_m - alpha_f;
471: beta = (PetscReal)0.5 * (1 + alpha_m - alpha_f); beta *= beta;
472: TSAlpha2SetParams(ts,alpha_m,alpha_f,gamma,beta);
473: return(0);
474: }
476: static PetscErrorCode TSAlpha2SetParams_Alpha(TS ts,PetscReal alpha_m,PetscReal alpha_f,PetscReal gamma,PetscReal beta)
477: {
478: TS_Alpha *th = (TS_Alpha*)ts->data;
479: PetscReal tol = 100*PETSC_MACHINE_EPSILON;
480: PetscReal res = ((PetscReal)0.5 + alpha_m - alpha_f) - gamma;
483: th->Alpha_m = alpha_m;
484: th->Alpha_f = alpha_f;
485: th->Gamma = gamma;
486: th->Beta = beta;
487: th->order = (PetscAbsReal(res) < tol) ? 2 : 1;
488: return(0);
489: }
491: static PetscErrorCode TSAlpha2GetParams_Alpha(TS ts,PetscReal *alpha_m,PetscReal *alpha_f,PetscReal *gamma,PetscReal *beta)
492: {
493: TS_Alpha *th = (TS_Alpha*)ts->data;
496: if (alpha_m) *alpha_m = th->Alpha_m;
497: if (alpha_f) *alpha_f = th->Alpha_f;
498: if (gamma) *gamma = th->Gamma;
499: if (beta) *beta = th->Beta;
500: return(0);
501: }
503: /*MC
504: TSALPHA2 - ODE/DAE solver using the implicit Generalized-Alpha method
505: for second-order systems
507: Level: beginner
509: References:
510: J. Chung, G.M.Hubert. "A Time Integration Algorithm for Structural
511: Dynamics with Improved Numerical Dissipation: The Generalized-alpha
512: Method" ASME Journal of Applied Mechanics, 60, 371:375, 1993.
514: .seealso: TS, TSCreate(), TSSetType(), TSAlpha2SetRadius(), TSAlpha2SetParams()
515: M*/
516: PETSC_EXTERN PetscErrorCode TSCreate_Alpha2(TS ts)
517: {
518: TS_Alpha *th;
522: ts->ops->reset = TSReset_Alpha;
523: ts->ops->destroy = TSDestroy_Alpha;
524: ts->ops->view = TSView_Alpha;
525: ts->ops->setup = TSSetUp_Alpha;
526: ts->ops->setfromoptions = TSSetFromOptions_Alpha;
527: ts->ops->step = TSStep_Alpha;
528: ts->ops->evaluatewlte = TSEvaluateWLTE_Alpha;
529: ts->ops->rollback = TSRollBack_Alpha;
530: /*ts->ops->interpolate = TSInterpolate_Alpha;*/
531: ts->ops->snesfunction = SNESTSFormFunction_Alpha;
532: ts->ops->snesjacobian = SNESTSFormJacobian_Alpha;
533: ts->default_adapt_type = TSADAPTNONE;
535: ts->usessnes = PETSC_TRUE;
537: PetscNewLog(ts,&th);
538: ts->data = (void*)th;
540: th->Alpha_m = 0.5;
541: th->Alpha_f = 0.5;
542: th->Gamma = 0.5;
543: th->Beta = 0.25;
544: th->order = 2;
546: PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2SetRadius_C",TSAlpha2SetRadius_Alpha);
547: PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2SetParams_C",TSAlpha2SetParams_Alpha);
548: PetscObjectComposeFunction((PetscObject)ts,"TSAlpha2GetParams_C",TSAlpha2GetParams_Alpha);
549: return(0);
550: }
552: /*@
553: TSAlpha2SetRadius - sets the desired spectral radius of the method
554: (i.e. high-frequency numerical damping)
556: Logically Collective on TS
558: The algorithmic parameters \alpha_m and \alpha_f of the
559: generalized-\alpha method can be computed in terms of a specified
560: spectral radius \rho in [0,1] for infinite time step in order to
561: control high-frequency numerical damping:
562: \alpha_m = (2-\rho)/(1+\rho)
563: \alpha_f = 1/(1+\rho)
565: Input Parameter:
566: + ts - timestepping context
567: - radius - the desired spectral radius
569: Options Database:
570: . -ts_alpha_radius <radius>
572: Level: intermediate
574: .seealso: TSAlpha2SetParams(), TSAlpha2GetParams()
575: @*/
576: PetscErrorCode TSAlpha2SetRadius(TS ts,PetscReal radius)
577: {
583: if (radius < 0 || radius > 1) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Radius %g not in range [0,1]",(double)radius);
584: PetscTryMethod(ts,"TSAlpha2SetRadius_C",(TS,PetscReal),(ts,radius));
585: return(0);
586: }
588: /*@
589: TSAlpha2SetParams - sets the algorithmic parameters for TSALPHA2
591: Logically Collective on TS
593: Second-order accuracy can be obtained so long as:
594: \gamma = 1/2 + alpha_m - alpha_f
595: \beta = 1/4 (1 + alpha_m - alpha_f)^2
597: Unconditional stability requires:
598: \alpha_m >= \alpha_f >= 1/2
601: Input Parameter:
602: + ts - timestepping context
603: . \alpha_m - algorithmic paramenter
604: . \alpha_f - algorithmic paramenter
605: . \gamma - algorithmic paramenter
606: - \beta - algorithmic paramenter
608: Options Database:
609: + -ts_alpha_alpha_m <alpha_m>
610: . -ts_alpha_alpha_f <alpha_f>
611: . -ts_alpha_gamma <gamma>
612: - -ts_alpha_beta <beta>
614: Note:
615: Use of this function is normally only required to hack TSALPHA2 to
616: use a modified integration scheme. Users should call
617: TSAlpha2SetRadius() to set the desired spectral radius of the methods
618: (i.e. high-frequency damping) in order so select optimal values for
619: these parameters.
621: Level: advanced
623: .seealso: TSAlpha2SetRadius(), TSAlpha2GetParams()
624: @*/
625: PetscErrorCode TSAlpha2SetParams(TS ts,PetscReal alpha_m,PetscReal alpha_f,PetscReal gamma,PetscReal beta)
626: {
635: PetscTryMethod(ts,"TSAlpha2SetParams_C",(TS,PetscReal,PetscReal,PetscReal,PetscReal),(ts,alpha_m,alpha_f,gamma,beta));
636: return(0);
637: }
639: /*@
640: TSAlpha2GetParams - gets the algorithmic parameters for TSALPHA2
642: Not Collective
644: Input Parameter:
645: . ts - timestepping context
647: Output Parameters:
648: + \alpha_m - algorithmic parameter
649: . \alpha_f - algorithmic parameter
650: . \gamma - algorithmic parameter
651: - \beta - algorithmic parameter
653: Note:
654: Use of this function is normally only required to hack TSALPHA2 to
655: use a modified integration scheme. Users should call
656: TSAlpha2SetRadius() to set the high-frequency damping (i.e. spectral
657: radius of the method) in order so select optimal values for these
658: parameters.
660: Level: advanced
662: .seealso: TSAlpha2SetRadius(), TSAlpha2SetParams()
663: @*/
664: PetscErrorCode TSAlpha2GetParams(TS ts,PetscReal *alpha_m,PetscReal *alpha_f,PetscReal *gamma,PetscReal *beta)
665: {
674: PetscUseMethod(ts,"TSAlpha2GetParams_C",(TS,PetscReal*,PetscReal*,PetscReal*,PetscReal*),(ts,alpha_m,alpha_f,gamma,beta));
675: return(0);
676: }