Actual source code: euler.c
1: /*
2: Code for Timestepping with explicit Euler.
3: */
4: #include <petsc/private/tsimpl.h>
6: typedef struct {
7: Vec update; /* work vector where new solution is formed */
8: } TS_Euler;
10: static PetscErrorCode TSStep_Euler(TS ts)
11: {
12: TS_Euler *euler = (TS_Euler *)ts->data;
13: Vec solution = ts->vec_sol, update = euler->update;
14: PetscBool stageok, accept = PETSC_TRUE;
15: PetscReal next_time_step = ts->time_step;
17: PetscFunctionBegin;
18: PetscCall(TSPreStage(ts, ts->ptime));
19: PetscCall(TSComputeRHSFunction(ts, ts->ptime, solution, update));
20: PetscCall(VecAYPX(update, ts->time_step, solution));
21: PetscCall(TSPostStage(ts, ts->ptime, 0, &solution));
22: PetscCall(TSAdaptCheckStage(ts->adapt, ts, ts->ptime, solution, &stageok));
23: if (!stageok) {
24: ts->reason = TS_DIVERGED_STEP_REJECTED;
25: PetscFunctionReturn(PETSC_SUCCESS);
26: }
27: PetscCall(TSFunctionDomainError(ts, ts->ptime + ts->time_step, update, &stageok));
28: if (!stageok) {
29: ts->reason = TS_DIVERGED_STEP_REJECTED;
30: PetscFunctionReturn(PETSC_SUCCESS);
31: }
33: PetscCall(TSAdaptChoose(ts->adapt, ts, ts->time_step, NULL, &next_time_step, &accept));
34: if (!accept) {
35: ts->reason = TS_DIVERGED_STEP_REJECTED;
36: PetscFunctionReturn(PETSC_SUCCESS);
37: }
38: PetscCall(VecCopy(update, solution));
40: ts->ptime += ts->time_step;
41: ts->time_step = next_time_step;
42: PetscFunctionReturn(PETSC_SUCCESS);
43: }
44: /*------------------------------------------------------------*/
46: static PetscErrorCode TSSetUp_Euler(TS ts)
47: {
48: TS_Euler *euler = (TS_Euler *)ts->data;
50: PetscFunctionBegin;
51: PetscCall(TSCheckImplicitTerm(ts));
52: PetscCall(VecDuplicate(ts->vec_sol, &euler->update));
53: PetscCall(TSGetAdapt(ts, &ts->adapt));
54: PetscCall(TSAdaptCandidatesClear(ts->adapt));
55: PetscFunctionReturn(PETSC_SUCCESS);
56: }
58: static PetscErrorCode TSReset_Euler(TS ts)
59: {
60: TS_Euler *euler = (TS_Euler *)ts->data;
62: PetscFunctionBegin;
63: PetscCall(VecDestroy(&euler->update));
64: PetscFunctionReturn(PETSC_SUCCESS);
65: }
67: static PetscErrorCode TSDestroy_Euler(TS ts)
68: {
69: PetscFunctionBegin;
70: PetscCall(TSReset_Euler(ts));
71: PetscCall(PetscFree(ts->data));
72: PetscFunctionReturn(PETSC_SUCCESS);
73: }
74: /*------------------------------------------------------------*/
76: static PetscErrorCode TSSetFromOptions_Euler(TS ts, PetscOptionItems *PetscOptionsObject)
77: {
78: PetscFunctionBegin;
79: PetscFunctionReturn(PETSC_SUCCESS);
80: }
82: static PetscErrorCode TSView_Euler(TS ts, PetscViewer viewer)
83: {
84: PetscFunctionBegin;
85: PetscFunctionReturn(PETSC_SUCCESS);
86: }
88: static PetscErrorCode TSInterpolate_Euler(TS ts, PetscReal t, Vec X)
89: {
90: TS_Euler *euler = (TS_Euler *)ts->data;
91: Vec update = euler->update;
92: PetscReal alpha = (ts->ptime - t) / ts->time_step;
94: PetscFunctionBegin;
95: PetscCall(VecWAXPY(X, -ts->time_step, update, ts->vec_sol));
96: PetscCall(VecAXPBY(X, 1.0 - alpha, alpha, ts->vec_sol));
97: PetscFunctionReturn(PETSC_SUCCESS);
98: }
100: static PetscErrorCode TSComputeLinearStability_Euler(TS ts, PetscReal xr, PetscReal xi, PetscReal *yr, PetscReal *yi)
101: {
102: PetscFunctionBegin;
103: *yr = 1.0 + xr;
104: *yi = xi;
105: PetscFunctionReturn(PETSC_SUCCESS);
106: }
107: /* ------------------------------------------------------------ */
109: /*MC
110: TSEULER - ODE solver using the explicit forward Euler method
112: Level: beginner
114: .seealso: [](ch_ts), `TSCreate()`, `TS`, `TSSetType()`, `TSBEULER`, `TSType`
115: M*/
116: PETSC_EXTERN PetscErrorCode TSCreate_Euler(TS ts)
117: {
118: TS_Euler *euler;
120: PetscFunctionBegin;
121: PetscCall(PetscNew(&euler));
122: ts->data = (void *)euler;
124: ts->ops->setup = TSSetUp_Euler;
125: ts->ops->step = TSStep_Euler;
126: ts->ops->reset = TSReset_Euler;
127: ts->ops->destroy = TSDestroy_Euler;
128: ts->ops->setfromoptions = TSSetFromOptions_Euler;
129: ts->ops->view = TSView_Euler;
130: ts->ops->interpolate = TSInterpolate_Euler;
131: ts->ops->linearstability = TSComputeLinearStability_Euler;
132: ts->default_adapt_type = TSADAPTNONE;
133: ts->usessnes = PETSC_FALSE;
134: PetscFunctionReturn(PETSC_SUCCESS);
135: }