xref: /petsc/src/ts/impls/mimex/mimex.c (revision ea844a1adba28e307898a6e94a1f422fd7d2db48)
1abadfa0fSMatthew G. Knepley /*
2abadfa0fSMatthew G. Knepley        Code for Timestepping with my makeshift IMEX.
3abadfa0fSMatthew G. Knepley */
4af0996ceSBarry Smith #include <petsc/private/tsimpl.h>                /*I   "petscts.h"   I*/
5abadfa0fSMatthew G. Knepley #include <petscds.h>
6*ea844a1aSMatthew Knepley #include <petscsection.h>
7abadfa0fSMatthew G. Knepley #include <petscdmplex.h>
8abadfa0fSMatthew G. Knepley 
9abadfa0fSMatthew G. Knepley typedef struct {
10010837a9SMatthew G. Knepley   Vec       Xdot, update;
11abadfa0fSMatthew G. Knepley   PetscReal stage_time;
1218c55e3fSMatthew G. Knepley   PetscInt  version;
13abadfa0fSMatthew G. Knepley } TS_Mimex;
14abadfa0fSMatthew G. Knepley 
15abadfa0fSMatthew G. Knepley static PetscErrorCode TSMimexGetX0AndXdot(TS ts, DM dm, Vec *X0, Vec *Xdot)
16abadfa0fSMatthew G. Knepley {
17abadfa0fSMatthew G. Knepley   TS_Mimex      *mimex = (TS_Mimex *) ts->data;
18abadfa0fSMatthew G. Knepley   PetscErrorCode ierr;
19abadfa0fSMatthew G. Knepley 
20abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
21abadfa0fSMatthew G. Knepley   if (X0) {
22abadfa0fSMatthew G. Knepley     if (dm && dm != ts->dm) {ierr = DMGetNamedGlobalVector(dm, "TSMimex_X0", X0);CHKERRQ(ierr);}
23abadfa0fSMatthew G. Knepley     else                    {*X0  = ts->vec_sol;}
24abadfa0fSMatthew G. Knepley   }
25abadfa0fSMatthew G. Knepley   if (Xdot) {
26abadfa0fSMatthew G. Knepley     if (dm && dm != ts->dm) {ierr  = DMGetNamedGlobalVector(dm, "TSMimex_Xdot", Xdot);CHKERRQ(ierr);}
27abadfa0fSMatthew G. Knepley     else                    {*Xdot = mimex->Xdot;}
28abadfa0fSMatthew G. Knepley   }
29abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
30abadfa0fSMatthew G. Knepley }
31abadfa0fSMatthew G. Knepley 
32abadfa0fSMatthew G. Knepley static PetscErrorCode TSMimexRestoreX0AndXdot(TS ts, DM dm, Vec *X0, Vec *Xdot)
33abadfa0fSMatthew G. Knepley {
34abadfa0fSMatthew G. Knepley   PetscErrorCode ierr;
35abadfa0fSMatthew G. Knepley 
36abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
37abadfa0fSMatthew G. Knepley   if (X0)   if (dm && dm != ts->dm) {ierr = DMRestoreNamedGlobalVector(dm, "TSMimex_X0", X0);CHKERRQ(ierr);}
38abadfa0fSMatthew G. Knepley   if (Xdot) if (dm && dm != ts->dm) {ierr = DMRestoreNamedGlobalVector(dm, "TSMimex_Xdot", Xdot);CHKERRQ(ierr);}
39abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
40abadfa0fSMatthew G. Knepley }
41abadfa0fSMatthew G. Knepley 
4218c55e3fSMatthew G. Knepley static PetscErrorCode TSMimexGetXstarAndG(TS ts, DM dm, Vec *Xstar, Vec *G)
4318c55e3fSMatthew G. Knepley {
4418c55e3fSMatthew G. Knepley   PetscErrorCode ierr;
4518c55e3fSMatthew G. Knepley 
4618c55e3fSMatthew G. Knepley   PetscFunctionBegin;
47010837a9SMatthew G. Knepley   ierr = DMGetNamedGlobalVector(dm, "TSMimex_Xstar", Xstar);CHKERRQ(ierr);
48010837a9SMatthew G. Knepley   ierr = DMGetNamedGlobalVector(dm, "TSMimex_G", G);CHKERRQ(ierr);
4918c55e3fSMatthew G. Knepley   PetscFunctionReturn(0);
5018c55e3fSMatthew G. Knepley }
5118c55e3fSMatthew G. Knepley 
5218c55e3fSMatthew G. Knepley static PetscErrorCode TSMimexRestoreXstarAndG(TS ts, DM dm, Vec *Xstar, Vec *G)
5318c55e3fSMatthew G. Knepley {
54010837a9SMatthew G. Knepley   PetscErrorCode ierr;
55010837a9SMatthew G. Knepley 
5618c55e3fSMatthew G. Knepley   PetscFunctionBegin;
57010837a9SMatthew G. Knepley   ierr = DMRestoreNamedGlobalVector(dm, "TSMimex_Xstar", Xstar);CHKERRQ(ierr);
58010837a9SMatthew G. Knepley   ierr = DMRestoreNamedGlobalVector(dm, "TSMimex_G", G);CHKERRQ(ierr);
5918c55e3fSMatthew G. Knepley   PetscFunctionReturn(0);
6018c55e3fSMatthew G. Knepley }
6118c55e3fSMatthew G. Knepley 
62abadfa0fSMatthew G. Knepley /*
63abadfa0fSMatthew G. Knepley   This defines the nonlinear equation that is to be solved with SNES
64abadfa0fSMatthew G. Knepley   G(U) = F[t0+dt, U, (U-U0)*shift] = 0
65abadfa0fSMatthew G. Knepley */
66abadfa0fSMatthew G. Knepley static PetscErrorCode SNESTSFormFunction_Mimex(SNES snes, Vec x, Vec y, TS ts)
67abadfa0fSMatthew G. Knepley {
68abadfa0fSMatthew G. Knepley   TS_Mimex      *mimex = (TS_Mimex *) ts->data;
69abadfa0fSMatthew G. Knepley   DM             dm, dmsave;
70abadfa0fSMatthew G. Knepley   Vec            X0, Xdot;
71abadfa0fSMatthew G. Knepley   PetscReal      shift = 1./ts->time_step;
72abadfa0fSMatthew G. Knepley   PetscErrorCode ierr;
73abadfa0fSMatthew G. Knepley 
74abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
75abadfa0fSMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
76abadfa0fSMatthew G. Knepley   ierr = TSMimexGetX0AndXdot(ts, dm, &X0, &Xdot);CHKERRQ(ierr);
77abadfa0fSMatthew G. Knepley   ierr = VecAXPBYPCZ(Xdot, -shift, shift, 0, X0, x);CHKERRQ(ierr);
78abadfa0fSMatthew G. Knepley 
79abadfa0fSMatthew G. Knepley   /* DM monkey-business allows user code to call TSGetDM() inside of functions evaluated on levels of FAS */
80abadfa0fSMatthew G. Knepley   dmsave = ts->dm;
81abadfa0fSMatthew G. Knepley   ts->dm = dm;
82abadfa0fSMatthew G. Knepley   ierr   = TSComputeIFunction(ts, mimex->stage_time, x, Xdot, y, PETSC_TRUE);CHKERRQ(ierr);
8318c55e3fSMatthew G. Knepley   if (mimex->version == 1) {
8418c55e3fSMatthew G. Knepley     DM                 dm;
8518c55e3fSMatthew G. Knepley     PetscDS            prob;
8618c55e3fSMatthew G. Knepley     PetscSection       s;
877e01ee02SMatthew G. Knepley     Vec                Xstar = NULL, G = NULL;
8818c55e3fSMatthew G. Knepley     const PetscScalar *ax;
8918c55e3fSMatthew G. Knepley     PetscScalar       *axstar;
9018c55e3fSMatthew G. Knepley     PetscInt           Nf, f, pStart, pEnd, p;
9118c55e3fSMatthew G. Knepley 
9218c55e3fSMatthew G. Knepley     ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
9318c55e3fSMatthew G. Knepley     ierr = DMGetDS(dm, &prob);CHKERRQ(ierr);
9492fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
9518c55e3fSMatthew G. Knepley     ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr);
9618c55e3fSMatthew G. Knepley     ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr);
9718c55e3fSMatthew G. Knepley     ierr = TSMimexGetXstarAndG(ts, dm, &Xstar, &G);CHKERRQ(ierr);
9818c55e3fSMatthew G. Knepley     ierr = VecCopy(X0, Xstar);CHKERRQ(ierr);
9918c55e3fSMatthew G. Knepley     ierr = VecGetArrayRead(x, &ax);CHKERRQ(ierr);
10018c55e3fSMatthew G. Knepley     ierr = VecGetArray(Xstar, &axstar);CHKERRQ(ierr);
10118c55e3fSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
10218c55e3fSMatthew G. Knepley       PetscBool implicit;
10318c55e3fSMatthew G. Knepley 
10418c55e3fSMatthew G. Knepley       ierr = PetscDSGetImplicit(prob, f, &implicit);CHKERRQ(ierr);
10518c55e3fSMatthew G. Knepley       if (!implicit) continue;
10618c55e3fSMatthew G. Knepley       for (p = pStart; p < pEnd; ++p) {
10718c55e3fSMatthew G. Knepley         PetscScalar *a, *axs;
10818c55e3fSMatthew G. Knepley         PetscInt     fdof, fcdof, d;
10918c55e3fSMatthew G. Knepley 
11018c55e3fSMatthew G. Knepley         ierr = PetscSectionGetFieldDof(s, p, f, &fdof);CHKERRQ(ierr);
11118c55e3fSMatthew G. Knepley         ierr = PetscSectionGetFieldConstraintDof(s, p, f, &fcdof);CHKERRQ(ierr);
11218c55e3fSMatthew G. Knepley         ierr = DMPlexPointGlobalFieldRead(dm, p, f, ax, &a);CHKERRQ(ierr);
11318c55e3fSMatthew G. Knepley         ierr = DMPlexPointGlobalFieldRef(dm, p, f, axstar, &axs);CHKERRQ(ierr);
11418c55e3fSMatthew G. Knepley         for (d = 0; d < fdof-fcdof; ++d) axs[d] = a[d];
11518c55e3fSMatthew G. Knepley       }
11618c55e3fSMatthew G. Knepley     }
11718c55e3fSMatthew G. Knepley     ierr = VecRestoreArrayRead(x, &ax);CHKERRQ(ierr);
11818c55e3fSMatthew G. Knepley     ierr = VecRestoreArray(Xstar, &axstar);CHKERRQ(ierr);
11918c55e3fSMatthew G. Knepley     ierr = TSComputeRHSFunction(ts, ts->ptime, Xstar, G);CHKERRQ(ierr);
12018c55e3fSMatthew G. Knepley     ierr = VecAXPY(y, -1.0, G);CHKERRQ(ierr);
12118c55e3fSMatthew G. Knepley     ierr = TSMimexRestoreXstarAndG(ts, dm, &Xstar, &G);CHKERRQ(ierr);
12218c55e3fSMatthew G. Knepley   }
123abadfa0fSMatthew G. Knepley   ts->dm = dmsave;
124abadfa0fSMatthew G. Knepley   ierr   = TSMimexRestoreX0AndXdot(ts, dm, &X0, &Xdot);CHKERRQ(ierr);
125abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
126abadfa0fSMatthew G. Knepley }
127abadfa0fSMatthew G. Knepley 
128abadfa0fSMatthew G. Knepley static PetscErrorCode SNESTSFormJacobian_Mimex(SNES snes, Vec x, Mat A, Mat B, TS ts)
129abadfa0fSMatthew G. Knepley {
130abadfa0fSMatthew G. Knepley   TS_Mimex      *mimex = (TS_Mimex *) ts->data;
131abadfa0fSMatthew G. Knepley   DM             dm, dmsave;
132abadfa0fSMatthew G. Knepley   Vec            Xdot;
133abadfa0fSMatthew G. Knepley   PetscReal      shift = 1./ts->time_step;
134abadfa0fSMatthew G. Knepley   PetscErrorCode ierr;
135abadfa0fSMatthew G. Knepley 
136abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
137abadfa0fSMatthew G. Knepley   /* th->Xdot has already been computed in SNESTSFormFunction_Mimex (SNES guarantees this) */
138abadfa0fSMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
139abadfa0fSMatthew G. Knepley   ierr = TSMimexGetX0AndXdot(ts, dm, NULL, &Xdot);CHKERRQ(ierr);
140abadfa0fSMatthew G. Knepley 
141abadfa0fSMatthew G. Knepley   /* DM monkey-business allows user code to call TSGetDM() inside of functions evaluated on levels of FAS */
142abadfa0fSMatthew G. Knepley   dmsave = ts->dm;
143abadfa0fSMatthew G. Knepley   ts->dm = dm;
144abadfa0fSMatthew G. Knepley   ierr   = TSComputeIJacobian(ts, mimex->stage_time, x, Xdot, shift, A, B, PETSC_TRUE);CHKERRQ(ierr);
145abadfa0fSMatthew G. Knepley   ts->dm = dmsave;
146abadfa0fSMatthew G. Knepley   ierr   = TSMimexRestoreX0AndXdot(ts, dm, NULL, &Xdot);CHKERRQ(ierr);
147abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
148abadfa0fSMatthew G. Knepley }
149abadfa0fSMatthew G. Knepley 
15018c55e3fSMatthew G. Knepley static PetscErrorCode TSStep_Mimex_Split(TS ts)
151abadfa0fSMatthew G. Knepley {
152abadfa0fSMatthew G. Knepley   TS_Mimex          *mimex = (TS_Mimex *) ts->data;
153abadfa0fSMatthew G. Knepley   DM                 dm;
154abadfa0fSMatthew G. Knepley   PetscDS            prob;
155abadfa0fSMatthew G. Knepley   PetscSection       s;
156abadfa0fSMatthew G. Knepley   Vec                sol = ts->vec_sol, update = mimex->update;
157abadfa0fSMatthew G. Knepley   const PetscScalar *aupdate;
158abadfa0fSMatthew G. Knepley   PetscScalar       *asol, dt = ts->time_step;
159abadfa0fSMatthew G. Knepley   PetscInt           Nf, f, pStart, pEnd, p;
160abadfa0fSMatthew G. Knepley   PetscErrorCode     ierr;
161abadfa0fSMatthew G. Knepley 
162abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
163abadfa0fSMatthew G. Knepley   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
164abadfa0fSMatthew G. Knepley   ierr = DMGetDS(dm, &prob);CHKERRQ(ierr);
16592fd8e1eSJed Brown   ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
166abadfa0fSMatthew G. Knepley   ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr);
167abadfa0fSMatthew G. Knepley   ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr);
168abadfa0fSMatthew G. Knepley   ierr = TSPreStage(ts, ts->ptime);CHKERRQ(ierr);
169abadfa0fSMatthew G. Knepley   /* Compute implicit update */
170abadfa0fSMatthew G. Knepley   mimex->stage_time = ts->ptime + ts->time_step;
171abadfa0fSMatthew G. Knepley   ierr = VecCopy(sol, update);CHKERRQ(ierr);
172abadfa0fSMatthew G. Knepley   ierr = SNESSolve(ts->snes, NULL, update);CHKERRQ(ierr);
173abadfa0fSMatthew G. Knepley   ierr = VecGetArrayRead(update, &aupdate);CHKERRQ(ierr);
174abadfa0fSMatthew G. Knepley   ierr = VecGetArray(sol, &asol);CHKERRQ(ierr);
175abadfa0fSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
17618c55e3fSMatthew G. Knepley     PetscBool implicit;
177abadfa0fSMatthew G. Knepley 
17818c55e3fSMatthew G. Knepley     ierr = PetscDSGetImplicit(prob, f, &implicit);CHKERRQ(ierr);
17918c55e3fSMatthew G. Knepley     if (!implicit) continue;
180abadfa0fSMatthew G. Knepley     for (p = pStart; p < pEnd; ++p) {
181abadfa0fSMatthew G. Knepley       PetscScalar *au, *as;
182abadfa0fSMatthew G. Knepley       PetscInt     fdof, fcdof, d;
183abadfa0fSMatthew G. Knepley 
184abadfa0fSMatthew G. Knepley       ierr = PetscSectionGetFieldDof(s, p, f, &fdof);CHKERRQ(ierr);
185abadfa0fSMatthew G. Knepley       ierr = PetscSectionGetFieldConstraintDof(s, p, f, &fcdof);CHKERRQ(ierr);
186abadfa0fSMatthew G. Knepley       ierr = DMPlexPointGlobalFieldRead(dm, p, f, aupdate, &au);CHKERRQ(ierr);
187abadfa0fSMatthew G. Knepley       ierr = DMPlexPointGlobalFieldRef(dm, p, f, asol, &as);CHKERRQ(ierr);
188abadfa0fSMatthew G. Knepley       for (d = 0; d < fdof-fcdof; ++d) as[d] = au[d];
189abadfa0fSMatthew G. Knepley     }
190abadfa0fSMatthew G. Knepley   }
191abadfa0fSMatthew G. Knepley   ierr = VecRestoreArrayRead(update, &aupdate);CHKERRQ(ierr);
192abadfa0fSMatthew G. Knepley   ierr = VecRestoreArray(sol, &asol);CHKERRQ(ierr);
193abadfa0fSMatthew G. Knepley   /* Compute explicit update */
194abadfa0fSMatthew G. Knepley   ierr = TSComputeRHSFunction(ts, ts->ptime, sol, update);CHKERRQ(ierr);
195abadfa0fSMatthew G. Knepley   ierr = VecGetArrayRead(update, &aupdate);CHKERRQ(ierr);
196abadfa0fSMatthew G. Knepley   ierr = VecGetArray(sol, &asol);CHKERRQ(ierr);
197abadfa0fSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
19818c55e3fSMatthew G. Knepley     PetscBool implicit;
199abadfa0fSMatthew G. Knepley 
20018c55e3fSMatthew G. Knepley     ierr = PetscDSGetImplicit(prob, f, &implicit);CHKERRQ(ierr);
20118c55e3fSMatthew G. Knepley     if (implicit) continue;
202abadfa0fSMatthew G. Knepley     for (p = pStart; p < pEnd; ++p) {
203abadfa0fSMatthew G. Knepley       PetscScalar *au, *as;
204abadfa0fSMatthew G. Knepley       PetscInt     fdof, fcdof, d;
205abadfa0fSMatthew G. Knepley 
206abadfa0fSMatthew G. Knepley       ierr = PetscSectionGetFieldDof(s, p, f, &fdof);CHKERRQ(ierr);
207abadfa0fSMatthew G. Knepley       ierr = PetscSectionGetFieldConstraintDof(s, p, f, &fcdof);CHKERRQ(ierr);
208abadfa0fSMatthew G. Knepley       ierr = DMPlexPointGlobalFieldRead(dm, p, f, aupdate, &au);CHKERRQ(ierr);
209abadfa0fSMatthew G. Knepley       ierr = DMPlexPointGlobalFieldRef(dm, p, f, asol, &as);CHKERRQ(ierr);
210abadfa0fSMatthew G. Knepley       for (d = 0; d < fdof-fcdof; ++d) as[d] += dt*au[d];
211abadfa0fSMatthew G. Knepley     }
212abadfa0fSMatthew G. Knepley   }
213abadfa0fSMatthew G. Knepley   ierr = VecRestoreArrayRead(update, &aupdate);CHKERRQ(ierr);
214abadfa0fSMatthew G. Knepley   ierr = VecRestoreArray(sol, &asol);CHKERRQ(ierr);
215abadfa0fSMatthew G. Knepley   ierr = TSPostStage(ts, ts->ptime, 0, &sol);CHKERRQ(ierr);
216abadfa0fSMatthew G. Knepley   ts->ptime += ts->time_step;
217abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
218abadfa0fSMatthew G. Knepley }
219abadfa0fSMatthew G. Knepley 
22018c55e3fSMatthew G. Knepley 
22118c55e3fSMatthew G. Knepley /* Evalute F at U and G at U0 for explicit fields and U for implicit fields */
22218c55e3fSMatthew G. Knepley static PetscErrorCode TSStep_Mimex_Implicit(TS ts)
22318c55e3fSMatthew G. Knepley {
22418c55e3fSMatthew G. Knepley   TS_Mimex      *mimex  = (TS_Mimex *) ts->data;
22518c55e3fSMatthew G. Knepley   Vec            sol    = ts->vec_sol;
22618c55e3fSMatthew G. Knepley   Vec            update = mimex->update;
22718c55e3fSMatthew G. Knepley   PetscErrorCode ierr;
22818c55e3fSMatthew G. Knepley 
22918c55e3fSMatthew G. Knepley   PetscFunctionBegin;
23018c55e3fSMatthew G. Knepley   ierr = TSPreStage(ts, ts->ptime);CHKERRQ(ierr);
23118c55e3fSMatthew G. Knepley   /* Compute implicit update */
23218c55e3fSMatthew G. Knepley   mimex->stage_time = ts->ptime + ts->time_step;
23318c55e3fSMatthew G. Knepley   ts->ptime += ts->time_step;
23418c55e3fSMatthew G. Knepley   ierr = VecCopy(sol, update);CHKERRQ(ierr);
23518c55e3fSMatthew G. Knepley   ierr = SNESSolve(ts->snes, NULL, update);CHKERRQ(ierr);
23618c55e3fSMatthew G. Knepley   ierr = VecCopy(update, sol);CHKERRQ(ierr);
23718c55e3fSMatthew G. Knepley   ierr = TSPostStage(ts, ts->ptime, 0, &sol);CHKERRQ(ierr);
23818c55e3fSMatthew G. Knepley   PetscFunctionReturn(0);
23918c55e3fSMatthew G. Knepley }
24018c55e3fSMatthew G. Knepley 
24118c55e3fSMatthew G. Knepley static PetscErrorCode TSStep_Mimex(TS ts)
24218c55e3fSMatthew G. Knepley {
24318c55e3fSMatthew G. Knepley   TS_Mimex       *mimex = (TS_Mimex*)ts->data;
24418c55e3fSMatthew G. Knepley   PetscErrorCode  ierr;
24518c55e3fSMatthew G. Knepley 
24618c55e3fSMatthew G. Knepley   PetscFunctionBegin;
24718c55e3fSMatthew G. Knepley   switch(mimex->version) {
24818c55e3fSMatthew G. Knepley   case 0:
24918c55e3fSMatthew G. Knepley     ierr = TSStep_Mimex_Split(ts);CHKERRQ(ierr); break;
25018c55e3fSMatthew G. Knepley   case 1:
25118c55e3fSMatthew G. Knepley     ierr = TSStep_Mimex_Implicit(ts);CHKERRQ(ierr); break;
25218c55e3fSMatthew G. Knepley   default:
25318c55e3fSMatthew G. Knepley     SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_OUTOFRANGE, "Unknown MIMEX version %d", mimex->version);
25418c55e3fSMatthew G. Knepley   }
25518c55e3fSMatthew G. Knepley   PetscFunctionReturn(0);
25618c55e3fSMatthew G. Knepley }
25718c55e3fSMatthew G. Knepley 
258abadfa0fSMatthew G. Knepley /*------------------------------------------------------------*/
259abadfa0fSMatthew G. Knepley 
260abadfa0fSMatthew G. Knepley static PetscErrorCode TSSetUp_Mimex(TS ts)
261abadfa0fSMatthew G. Knepley {
262abadfa0fSMatthew G. Knepley   TS_Mimex       *mimex = (TS_Mimex*)ts->data;
263abadfa0fSMatthew G. Knepley   PetscErrorCode ierr;
264abadfa0fSMatthew G. Knepley 
265abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
266abadfa0fSMatthew G. Knepley   ierr = VecDuplicate(ts->vec_sol, &mimex->update);CHKERRQ(ierr);
267abadfa0fSMatthew G. Knepley   ierr = VecDuplicate(ts->vec_sol, &mimex->Xdot);CHKERRQ(ierr);
268abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
269abadfa0fSMatthew G. Knepley }
270abadfa0fSMatthew G. Knepley 
271abadfa0fSMatthew G. Knepley static PetscErrorCode TSReset_Mimex(TS ts)
272abadfa0fSMatthew G. Knepley {
273abadfa0fSMatthew G. Knepley   TS_Mimex       *mimex = (TS_Mimex*)ts->data;
274abadfa0fSMatthew G. Knepley   PetscErrorCode ierr;
275abadfa0fSMatthew G. Knepley 
276abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
277abadfa0fSMatthew G. Knepley   ierr = VecDestroy(&mimex->update);CHKERRQ(ierr);
278abadfa0fSMatthew G. Knepley   ierr = VecDestroy(&mimex->Xdot);CHKERRQ(ierr);
279abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
280abadfa0fSMatthew G. Knepley }
281abadfa0fSMatthew G. Knepley 
282abadfa0fSMatthew G. Knepley static PetscErrorCode TSDestroy_Mimex(TS ts)
283abadfa0fSMatthew G. Knepley {
284abadfa0fSMatthew G. Knepley   PetscErrorCode ierr;
285abadfa0fSMatthew G. Knepley 
286abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
287abadfa0fSMatthew G. Knepley   ierr = TSReset_Mimex(ts);CHKERRQ(ierr);
288abadfa0fSMatthew G. Knepley   ierr = PetscFree(ts->data);CHKERRQ(ierr);
289abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
290abadfa0fSMatthew G. Knepley }
291abadfa0fSMatthew G. Knepley /*------------------------------------------------------------*/
292abadfa0fSMatthew G. Knepley 
2934416b707SBarry Smith static PetscErrorCode TSSetFromOptions_Mimex(PetscOptionItems *PetscOptionsObject, TS ts)
294abadfa0fSMatthew G. Knepley {
29518c55e3fSMatthew G. Knepley   TS_Mimex      *mimex = (TS_Mimex *) ts->data;
29618c55e3fSMatthew G. Knepley   PetscErrorCode ierr;
29718c55e3fSMatthew G. Knepley 
298abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
29918c55e3fSMatthew G. Knepley   ierr = PetscOptionsHead(PetscOptionsObject, "MIMEX ODE solver options");CHKERRQ(ierr);
30018c55e3fSMatthew G. Knepley   {
30118c55e3fSMatthew G. Knepley     ierr = PetscOptionsInt("-ts_mimex_version", "Algorithm version", "TSMimexSetVersion", mimex->version, &mimex->version, NULL);CHKERRQ(ierr);
30218c55e3fSMatthew G. Knepley   }
30318c55e3fSMatthew G. Knepley   ierr = PetscOptionsTail();CHKERRQ(ierr);
304abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
305abadfa0fSMatthew G. Knepley }
306abadfa0fSMatthew G. Knepley 
307abadfa0fSMatthew G. Knepley static PetscErrorCode TSView_Mimex(TS ts,PetscViewer viewer)
308abadfa0fSMatthew G. Knepley {
3095bf398f3SMatthew G. Knepley   TS_Mimex      *mimex = (TS_Mimex *) ts->data;
3105bf398f3SMatthew G. Knepley   PetscBool      iascii;
3115bf398f3SMatthew G. Knepley   PetscErrorCode ierr;
3125bf398f3SMatthew G. Knepley 
313abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
3145bf398f3SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
3155bf398f3SMatthew G. Knepley   if (iascii) {
3165bf398f3SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "  Version = %D\n", mimex->version);CHKERRQ(ierr);
3175bf398f3SMatthew G. Knepley   }
318abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
319abadfa0fSMatthew G. Knepley }
320abadfa0fSMatthew G. Knepley 
321abadfa0fSMatthew G. Knepley static PetscErrorCode TSInterpolate_Mimex(TS ts,PetscReal t,Vec X)
322abadfa0fSMatthew G. Knepley {
323abadfa0fSMatthew G. Knepley   PetscReal      alpha = (ts->ptime - t)/ts->time_step;
324abadfa0fSMatthew G. Knepley   PetscErrorCode ierr;
325abadfa0fSMatthew G. Knepley 
326abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
327abadfa0fSMatthew G. Knepley   ierr = VecAXPBY(ts->vec_sol,1.0-alpha,alpha,X);CHKERRQ(ierr);
328abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
329abadfa0fSMatthew G. Knepley }
330abadfa0fSMatthew G. Knepley 
331560360afSLisandro Dalcin static PetscErrorCode TSComputeLinearStability_Mimex(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
332abadfa0fSMatthew G. Knepley {
333abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
334abadfa0fSMatthew G. Knepley   *yr = 1.0 + xr;
335abadfa0fSMatthew G. Knepley   *yi = xi;
336abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
337abadfa0fSMatthew G. Knepley }
338abadfa0fSMatthew G. Knepley /* ------------------------------------------------------------ */
339abadfa0fSMatthew G. Knepley 
340abadfa0fSMatthew G. Knepley /*MC
341abadfa0fSMatthew G. Knepley       TSMIMEX - ODE solver using the explicit forward Mimex method
342abadfa0fSMatthew G. Knepley 
343abadfa0fSMatthew G. Knepley   Level: beginner
344abadfa0fSMatthew G. Knepley 
345abadfa0fSMatthew G. Knepley .seealso:  TSCreate(), TS, TSSetType(), TSBEULER
346abadfa0fSMatthew G. Knepley 
347abadfa0fSMatthew G. Knepley M*/
348abadfa0fSMatthew G. Knepley PETSC_EXTERN PetscErrorCode TSCreate_Mimex(TS ts)
349abadfa0fSMatthew G. Knepley {
350abadfa0fSMatthew G. Knepley   TS_Mimex       *mimex;
351abadfa0fSMatthew G. Knepley   PetscErrorCode ierr;
352abadfa0fSMatthew G. Knepley 
353abadfa0fSMatthew G. Knepley   PetscFunctionBegin;
354abadfa0fSMatthew G. Knepley   ts->ops->setup           = TSSetUp_Mimex;
355abadfa0fSMatthew G. Knepley   ts->ops->step            = TSStep_Mimex;
356abadfa0fSMatthew G. Knepley   ts->ops->reset           = TSReset_Mimex;
357abadfa0fSMatthew G. Knepley   ts->ops->destroy         = TSDestroy_Mimex;
358abadfa0fSMatthew G. Knepley   ts->ops->setfromoptions  = TSSetFromOptions_Mimex;
359abadfa0fSMatthew G. Knepley   ts->ops->view            = TSView_Mimex;
360abadfa0fSMatthew G. Knepley   ts->ops->interpolate     = TSInterpolate_Mimex;
361abadfa0fSMatthew G. Knepley   ts->ops->linearstability = TSComputeLinearStability_Mimex;
362abadfa0fSMatthew G. Knepley   ts->ops->snesfunction    = SNESTSFormFunction_Mimex;
363abadfa0fSMatthew G. Knepley   ts->ops->snesjacobian    = SNESTSFormJacobian_Mimex;
3642ffb9264SLisandro Dalcin   ts->default_adapt_type   = TSADAPTNONE;
365abadfa0fSMatthew G. Knepley 
366abadfa0fSMatthew G. Knepley   ierr = PetscNewLog(ts,&mimex);CHKERRQ(ierr);
367abadfa0fSMatthew G. Knepley   ts->data = (void*)mimex;
368fdc0a3ceSMatthew G. Knepley 
369fdc0a3ceSMatthew G. Knepley   mimex->version = 1;
370abadfa0fSMatthew G. Knepley   PetscFunctionReturn(0);
371abadfa0fSMatthew G. Knepley }
372