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> 6ea844a1aSMatthew 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 159371c9d4SSatish Balay static PetscErrorCode TSMimexGetX0AndXdot(TS ts, DM dm, Vec *X0, Vec *Xdot) { 16abadfa0fSMatthew G. Knepley TS_Mimex *mimex = (TS_Mimex *)ts->data; 17abadfa0fSMatthew G. Knepley 18abadfa0fSMatthew G. Knepley PetscFunctionBegin; 19abadfa0fSMatthew G. Knepley if (X0) { 209566063dSJacob Faibussowitsch if (dm && dm != ts->dm) PetscCall(DMGetNamedGlobalVector(dm, "TSMimex_X0", X0)); 21abadfa0fSMatthew G. Knepley else { *X0 = ts->vec_sol; } 22abadfa0fSMatthew G. Knepley } 23abadfa0fSMatthew G. Knepley if (Xdot) { 249566063dSJacob Faibussowitsch if (dm && dm != ts->dm) PetscCall(DMGetNamedGlobalVector(dm, "TSMimex_Xdot", Xdot)); 25abadfa0fSMatthew G. Knepley else { *Xdot = mimex->Xdot; } 26abadfa0fSMatthew G. Knepley } 27abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 28abadfa0fSMatthew G. Knepley } 29abadfa0fSMatthew G. Knepley 309371c9d4SSatish Balay static PetscErrorCode TSMimexRestoreX0AndXdot(TS ts, DM dm, Vec *X0, Vec *Xdot) { 31abadfa0fSMatthew G. Knepley PetscFunctionBegin; 329371c9d4SSatish Balay if (X0) 339371c9d4SSatish Balay if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSMimex_X0", X0)); 349371c9d4SSatish Balay if (Xdot) 359371c9d4SSatish Balay if (dm && dm != ts->dm) PetscCall(DMRestoreNamedGlobalVector(dm, "TSMimex_Xdot", Xdot)); 36abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 37abadfa0fSMatthew G. Knepley } 38abadfa0fSMatthew G. Knepley 399371c9d4SSatish Balay static PetscErrorCode TSMimexGetXstarAndG(TS ts, DM dm, Vec *Xstar, Vec *G) { 4018c55e3fSMatthew G. Knepley PetscFunctionBegin; 419566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dm, "TSMimex_Xstar", Xstar)); 429566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dm, "TSMimex_G", G)); 4318c55e3fSMatthew G. Knepley PetscFunctionReturn(0); 4418c55e3fSMatthew G. Knepley } 4518c55e3fSMatthew G. Knepley 469371c9d4SSatish Balay static PetscErrorCode TSMimexRestoreXstarAndG(TS ts, DM dm, Vec *Xstar, Vec *G) { 4718c55e3fSMatthew G. Knepley PetscFunctionBegin; 489566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedGlobalVector(dm, "TSMimex_Xstar", Xstar)); 499566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedGlobalVector(dm, "TSMimex_G", G)); 5018c55e3fSMatthew G. Knepley PetscFunctionReturn(0); 5118c55e3fSMatthew G. Knepley } 5218c55e3fSMatthew G. Knepley 53abadfa0fSMatthew G. Knepley /* 54abadfa0fSMatthew G. Knepley This defines the nonlinear equation that is to be solved with SNES 55abadfa0fSMatthew G. Knepley G(U) = F[t0+dt, U, (U-U0)*shift] = 0 56abadfa0fSMatthew G. Knepley */ 579371c9d4SSatish Balay static PetscErrorCode SNESTSFormFunction_Mimex(SNES snes, Vec x, Vec y, TS ts) { 58abadfa0fSMatthew G. Knepley TS_Mimex *mimex = (TS_Mimex *)ts->data; 59abadfa0fSMatthew G. Knepley DM dm, dmsave; 60abadfa0fSMatthew G. Knepley Vec X0, Xdot; 61abadfa0fSMatthew G. Knepley PetscReal shift = 1. / ts->time_step; 62abadfa0fSMatthew G. Knepley 63abadfa0fSMatthew G. Knepley PetscFunctionBegin; 649566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 659566063dSJacob Faibussowitsch PetscCall(TSMimexGetX0AndXdot(ts, dm, &X0, &Xdot)); 669566063dSJacob Faibussowitsch PetscCall(VecAXPBYPCZ(Xdot, -shift, shift, 0, X0, x)); 67abadfa0fSMatthew G. Knepley 68abadfa0fSMatthew G. Knepley /* DM monkey-business allows user code to call TSGetDM() inside of functions evaluated on levels of FAS */ 69abadfa0fSMatthew G. Knepley dmsave = ts->dm; 70abadfa0fSMatthew G. Knepley ts->dm = dm; 719566063dSJacob Faibussowitsch PetscCall(TSComputeIFunction(ts, mimex->stage_time, x, Xdot, y, PETSC_TRUE)); 7218c55e3fSMatthew G. Knepley if (mimex->version == 1) { 7318c55e3fSMatthew G. Knepley DM dm; 7418c55e3fSMatthew G. Knepley PetscDS prob; 7518c55e3fSMatthew G. Knepley PetscSection s; 767e01ee02SMatthew G. Knepley Vec Xstar = NULL, G = NULL; 7718c55e3fSMatthew G. Knepley const PetscScalar *ax; 7818c55e3fSMatthew G. Knepley PetscScalar *axstar; 7918c55e3fSMatthew G. Knepley PetscInt Nf, f, pStart, pEnd, p; 8018c55e3fSMatthew G. Knepley 819566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 829566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 839566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 849566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 859566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 869566063dSJacob Faibussowitsch PetscCall(TSMimexGetXstarAndG(ts, dm, &Xstar, &G)); 879566063dSJacob Faibussowitsch PetscCall(VecCopy(X0, Xstar)); 889566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &ax)); 899566063dSJacob Faibussowitsch PetscCall(VecGetArray(Xstar, &axstar)); 9018c55e3fSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9118c55e3fSMatthew G. Knepley PetscBool implicit; 9218c55e3fSMatthew G. Knepley 939566063dSJacob Faibussowitsch PetscCall(PetscDSGetImplicit(prob, f, &implicit)); 9418c55e3fSMatthew G. Knepley if (!implicit) continue; 9518c55e3fSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 9618c55e3fSMatthew G. Knepley PetscScalar *a, *axs; 9718c55e3fSMatthew G. Knepley PetscInt fdof, fcdof, d; 9818c55e3fSMatthew G. Knepley 999566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(s, p, f, &fdof)); 1009566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(s, p, f, &fcdof)); 1019566063dSJacob Faibussowitsch PetscCall(DMPlexPointGlobalFieldRead(dm, p, f, ax, &a)); 1029566063dSJacob Faibussowitsch PetscCall(DMPlexPointGlobalFieldRef(dm, p, f, axstar, &axs)); 10318c55e3fSMatthew G. Knepley for (d = 0; d < fdof - fcdof; ++d) axs[d] = a[d]; 10418c55e3fSMatthew G. Knepley } 10518c55e3fSMatthew G. Knepley } 1069566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &ax)); 1079566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Xstar, &axstar)); 1089566063dSJacob Faibussowitsch PetscCall(TSComputeRHSFunction(ts, ts->ptime, Xstar, G)); 1099566063dSJacob Faibussowitsch PetscCall(VecAXPY(y, -1.0, G)); 1109566063dSJacob Faibussowitsch PetscCall(TSMimexRestoreXstarAndG(ts, dm, &Xstar, &G)); 11118c55e3fSMatthew G. Knepley } 112abadfa0fSMatthew G. Knepley ts->dm = dmsave; 1139566063dSJacob Faibussowitsch PetscCall(TSMimexRestoreX0AndXdot(ts, dm, &X0, &Xdot)); 114abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 115abadfa0fSMatthew G. Knepley } 116abadfa0fSMatthew G. Knepley 1179371c9d4SSatish Balay static PetscErrorCode SNESTSFormJacobian_Mimex(SNES snes, Vec x, Mat A, Mat B, TS ts) { 118abadfa0fSMatthew G. Knepley TS_Mimex *mimex = (TS_Mimex *)ts->data; 119abadfa0fSMatthew G. Knepley DM dm, dmsave; 120abadfa0fSMatthew G. Knepley Vec Xdot; 121abadfa0fSMatthew G. Knepley PetscReal shift = 1. / ts->time_step; 122abadfa0fSMatthew G. Knepley 123abadfa0fSMatthew G. Knepley PetscFunctionBegin; 124abadfa0fSMatthew G. Knepley /* th->Xdot has already been computed in SNESTSFormFunction_Mimex (SNES guarantees this) */ 1259566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1269566063dSJacob Faibussowitsch PetscCall(TSMimexGetX0AndXdot(ts, dm, NULL, &Xdot)); 127abadfa0fSMatthew G. Knepley 128abadfa0fSMatthew G. Knepley /* DM monkey-business allows user code to call TSGetDM() inside of functions evaluated on levels of FAS */ 129abadfa0fSMatthew G. Knepley dmsave = ts->dm; 130abadfa0fSMatthew G. Knepley ts->dm = dm; 1319566063dSJacob Faibussowitsch PetscCall(TSComputeIJacobian(ts, mimex->stage_time, x, Xdot, shift, A, B, PETSC_TRUE)); 132abadfa0fSMatthew G. Knepley ts->dm = dmsave; 1339566063dSJacob Faibussowitsch PetscCall(TSMimexRestoreX0AndXdot(ts, dm, NULL, &Xdot)); 134abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 135abadfa0fSMatthew G. Knepley } 136abadfa0fSMatthew G. Knepley 1379371c9d4SSatish Balay static PetscErrorCode TSStep_Mimex_Split(TS ts) { 138abadfa0fSMatthew G. Knepley TS_Mimex *mimex = (TS_Mimex *)ts->data; 139abadfa0fSMatthew G. Knepley DM dm; 140abadfa0fSMatthew G. Knepley PetscDS prob; 141abadfa0fSMatthew G. Knepley PetscSection s; 142abadfa0fSMatthew G. Knepley Vec sol = ts->vec_sol, update = mimex->update; 143abadfa0fSMatthew G. Knepley const PetscScalar *aupdate; 144abadfa0fSMatthew G. Knepley PetscScalar *asol, dt = ts->time_step; 145abadfa0fSMatthew G. Knepley PetscInt Nf, f, pStart, pEnd, p; 146abadfa0fSMatthew G. Knepley 147abadfa0fSMatthew G. Knepley PetscFunctionBegin; 1489566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 1499566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 1509566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 1519566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 1529566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 1539566063dSJacob Faibussowitsch PetscCall(TSPreStage(ts, ts->ptime)); 154abadfa0fSMatthew G. Knepley /* Compute implicit update */ 155abadfa0fSMatthew G. Knepley mimex->stage_time = ts->ptime + ts->time_step; 1569566063dSJacob Faibussowitsch PetscCall(VecCopy(sol, update)); 1579566063dSJacob Faibussowitsch PetscCall(SNESSolve(ts->snes, NULL, update)); 1589566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(update, &aupdate)); 1599566063dSJacob Faibussowitsch PetscCall(VecGetArray(sol, &asol)); 160abadfa0fSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 16118c55e3fSMatthew G. Knepley PetscBool implicit; 162abadfa0fSMatthew G. Knepley 1639566063dSJacob Faibussowitsch PetscCall(PetscDSGetImplicit(prob, f, &implicit)); 16418c55e3fSMatthew G. Knepley if (!implicit) continue; 165abadfa0fSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 166abadfa0fSMatthew G. Knepley PetscScalar *au, *as; 167abadfa0fSMatthew G. Knepley PetscInt fdof, fcdof, d; 168abadfa0fSMatthew G. Knepley 1699566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(s, p, f, &fdof)); 1709566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(s, p, f, &fcdof)); 1719566063dSJacob Faibussowitsch PetscCall(DMPlexPointGlobalFieldRead(dm, p, f, aupdate, &au)); 1729566063dSJacob Faibussowitsch PetscCall(DMPlexPointGlobalFieldRef(dm, p, f, asol, &as)); 173abadfa0fSMatthew G. Knepley for (d = 0; d < fdof - fcdof; ++d) as[d] = au[d]; 174abadfa0fSMatthew G. Knepley } 175abadfa0fSMatthew G. Knepley } 1769566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(update, &aupdate)); 1779566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(sol, &asol)); 178abadfa0fSMatthew G. Knepley /* Compute explicit update */ 1799566063dSJacob Faibussowitsch PetscCall(TSComputeRHSFunction(ts, ts->ptime, sol, update)); 1809566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(update, &aupdate)); 1819566063dSJacob Faibussowitsch PetscCall(VecGetArray(sol, &asol)); 182abadfa0fSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 18318c55e3fSMatthew G. Knepley PetscBool implicit; 184abadfa0fSMatthew G. Knepley 1859566063dSJacob Faibussowitsch PetscCall(PetscDSGetImplicit(prob, f, &implicit)); 18618c55e3fSMatthew G. Knepley if (implicit) continue; 187abadfa0fSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 188abadfa0fSMatthew G. Knepley PetscScalar *au, *as; 189abadfa0fSMatthew G. Knepley PetscInt fdof, fcdof, d; 190abadfa0fSMatthew G. Knepley 1919566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(s, p, f, &fdof)); 1929566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(s, p, f, &fcdof)); 1939566063dSJacob Faibussowitsch PetscCall(DMPlexPointGlobalFieldRead(dm, p, f, aupdate, &au)); 1949566063dSJacob Faibussowitsch PetscCall(DMPlexPointGlobalFieldRef(dm, p, f, asol, &as)); 195abadfa0fSMatthew G. Knepley for (d = 0; d < fdof - fcdof; ++d) as[d] += dt * au[d]; 196abadfa0fSMatthew G. Knepley } 197abadfa0fSMatthew G. Knepley } 1989566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(update, &aupdate)); 1999566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(sol, &asol)); 2009566063dSJacob Faibussowitsch PetscCall(TSPostStage(ts, ts->ptime, 0, &sol)); 201abadfa0fSMatthew G. Knepley ts->ptime += ts->time_step; 202abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 203abadfa0fSMatthew G. Knepley } 204abadfa0fSMatthew G. Knepley 20518c55e3fSMatthew G. Knepley /* Evalute F at U and G at U0 for explicit fields and U for implicit fields */ 2069371c9d4SSatish Balay static PetscErrorCode TSStep_Mimex_Implicit(TS ts) { 20718c55e3fSMatthew G. Knepley TS_Mimex *mimex = (TS_Mimex *)ts->data; 20818c55e3fSMatthew G. Knepley Vec sol = ts->vec_sol; 20918c55e3fSMatthew G. Knepley Vec update = mimex->update; 21018c55e3fSMatthew G. Knepley 21118c55e3fSMatthew G. Knepley PetscFunctionBegin; 2129566063dSJacob Faibussowitsch PetscCall(TSPreStage(ts, ts->ptime)); 21318c55e3fSMatthew G. Knepley /* Compute implicit update */ 21418c55e3fSMatthew G. Knepley mimex->stage_time = ts->ptime + ts->time_step; 21518c55e3fSMatthew G. Knepley ts->ptime += ts->time_step; 2169566063dSJacob Faibussowitsch PetscCall(VecCopy(sol, update)); 2179566063dSJacob Faibussowitsch PetscCall(SNESSolve(ts->snes, NULL, update)); 2189566063dSJacob Faibussowitsch PetscCall(VecCopy(update, sol)); 2199566063dSJacob Faibussowitsch PetscCall(TSPostStage(ts, ts->ptime, 0, &sol)); 22018c55e3fSMatthew G. Knepley PetscFunctionReturn(0); 22118c55e3fSMatthew G. Knepley } 22218c55e3fSMatthew G. Knepley 2239371c9d4SSatish Balay static PetscErrorCode TSStep_Mimex(TS ts) { 22418c55e3fSMatthew G. Knepley TS_Mimex *mimex = (TS_Mimex *)ts->data; 22518c55e3fSMatthew G. Knepley 22618c55e3fSMatthew G. Knepley PetscFunctionBegin; 22718c55e3fSMatthew G. Knepley switch (mimex->version) { 2289371c9d4SSatish Balay case 0: PetscCall(TSStep_Mimex_Split(ts)); break; 2299371c9d4SSatish Balay case 1: PetscCall(TSStep_Mimex_Implicit(ts)); break; 2309371c9d4SSatish Balay default: SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Unknown MIMEX version %" PetscInt_FMT, mimex->version); 23118c55e3fSMatthew G. Knepley } 23218c55e3fSMatthew G. Knepley PetscFunctionReturn(0); 23318c55e3fSMatthew G. Knepley } 23418c55e3fSMatthew G. Knepley 235abadfa0fSMatthew G. Knepley /*------------------------------------------------------------*/ 236abadfa0fSMatthew G. Knepley 2379371c9d4SSatish Balay static PetscErrorCode TSSetUp_Mimex(TS ts) { 238abadfa0fSMatthew G. Knepley TS_Mimex *mimex = (TS_Mimex *)ts->data; 239abadfa0fSMatthew G. Knepley 240abadfa0fSMatthew G. Knepley PetscFunctionBegin; 2419566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &mimex->update)); 2429566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &mimex->Xdot)); 243abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 244abadfa0fSMatthew G. Knepley } 245abadfa0fSMatthew G. Knepley 2469371c9d4SSatish Balay static PetscErrorCode TSReset_Mimex(TS ts) { 247abadfa0fSMatthew G. Knepley TS_Mimex *mimex = (TS_Mimex *)ts->data; 248abadfa0fSMatthew G. Knepley 249abadfa0fSMatthew G. Knepley PetscFunctionBegin; 2509566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mimex->update)); 2519566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mimex->Xdot)); 252abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 253abadfa0fSMatthew G. Knepley } 254abadfa0fSMatthew G. Knepley 2559371c9d4SSatish Balay static PetscErrorCode TSDestroy_Mimex(TS ts) { 256abadfa0fSMatthew G. Knepley PetscFunctionBegin; 2579566063dSJacob Faibussowitsch PetscCall(TSReset_Mimex(ts)); 2589566063dSJacob Faibussowitsch PetscCall(PetscFree(ts->data)); 259abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 260abadfa0fSMatthew G. Knepley } 261abadfa0fSMatthew G. Knepley /*------------------------------------------------------------*/ 262abadfa0fSMatthew G. Knepley 2639371c9d4SSatish Balay static PetscErrorCode TSSetFromOptions_Mimex(TS ts, PetscOptionItems *PetscOptionsObject) { 26418c55e3fSMatthew G. Knepley TS_Mimex *mimex = (TS_Mimex *)ts->data; 26518c55e3fSMatthew G. Knepley 266abadfa0fSMatthew G. Knepley PetscFunctionBegin; 267d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "MIMEX ODE solver options"); 2689371c9d4SSatish Balay { PetscCall(PetscOptionsInt("-ts_mimex_version", "Algorithm version", "TSMimexSetVersion", mimex->version, &mimex->version, NULL)); } 269d0609cedSBarry Smith PetscOptionsHeadEnd(); 270abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 271abadfa0fSMatthew G. Knepley } 272abadfa0fSMatthew G. Knepley 2739371c9d4SSatish Balay static PetscErrorCode TSView_Mimex(TS ts, PetscViewer viewer) { 2745bf398f3SMatthew G. Knepley TS_Mimex *mimex = (TS_Mimex *)ts->data; 2755bf398f3SMatthew G. Knepley PetscBool iascii; 2765bf398f3SMatthew G. Knepley 277abadfa0fSMatthew G. Knepley PetscFunctionBegin; 2789566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 279*48a46eb9SPierre Jolivet if (iascii) PetscCall(PetscViewerASCIIPrintf(viewer, " Version = %" PetscInt_FMT "\n", mimex->version)); 280abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 281abadfa0fSMatthew G. Knepley } 282abadfa0fSMatthew G. Knepley 2839371c9d4SSatish Balay static PetscErrorCode TSInterpolate_Mimex(TS ts, PetscReal t, Vec X) { 284abadfa0fSMatthew G. Knepley PetscReal alpha = (ts->ptime - t) / ts->time_step; 285abadfa0fSMatthew G. Knepley 286abadfa0fSMatthew G. Knepley PetscFunctionBegin; 2879566063dSJacob Faibussowitsch PetscCall(VecAXPBY(ts->vec_sol, 1.0 - alpha, alpha, X)); 288abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 289abadfa0fSMatthew G. Knepley } 290abadfa0fSMatthew G. Knepley 2919371c9d4SSatish Balay static PetscErrorCode TSComputeLinearStability_Mimex(TS ts, PetscReal xr, PetscReal xi, PetscReal *yr, PetscReal *yi) { 292abadfa0fSMatthew G. Knepley PetscFunctionBegin; 293abadfa0fSMatthew G. Knepley *yr = 1.0 + xr; 294abadfa0fSMatthew G. Knepley *yi = xi; 295abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 296abadfa0fSMatthew G. Knepley } 297abadfa0fSMatthew G. Knepley /* ------------------------------------------------------------ */ 298abadfa0fSMatthew G. Knepley 299abadfa0fSMatthew G. Knepley /*MC 300abadfa0fSMatthew G. Knepley TSMIMEX - ODE solver using the explicit forward Mimex method 301abadfa0fSMatthew G. Knepley 302abadfa0fSMatthew G. Knepley Level: beginner 303abadfa0fSMatthew G. Knepley 304db781477SPatrick Sanan .seealso: `TSCreate()`, `TS`, `TSSetType()`, `TSBEULER` 305abadfa0fSMatthew G. Knepley 306abadfa0fSMatthew G. Knepley M*/ 3079371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode TSCreate_Mimex(TS ts) { 308abadfa0fSMatthew G. Knepley TS_Mimex *mimex; 309abadfa0fSMatthew G. Knepley 310abadfa0fSMatthew G. Knepley PetscFunctionBegin; 311abadfa0fSMatthew G. Knepley ts->ops->setup = TSSetUp_Mimex; 312abadfa0fSMatthew G. Knepley ts->ops->step = TSStep_Mimex; 313abadfa0fSMatthew G. Knepley ts->ops->reset = TSReset_Mimex; 314abadfa0fSMatthew G. Knepley ts->ops->destroy = TSDestroy_Mimex; 315abadfa0fSMatthew G. Knepley ts->ops->setfromoptions = TSSetFromOptions_Mimex; 316abadfa0fSMatthew G. Knepley ts->ops->view = TSView_Mimex; 317abadfa0fSMatthew G. Knepley ts->ops->interpolate = TSInterpolate_Mimex; 318abadfa0fSMatthew G. Knepley ts->ops->linearstability = TSComputeLinearStability_Mimex; 319abadfa0fSMatthew G. Knepley ts->ops->snesfunction = SNESTSFormFunction_Mimex; 320abadfa0fSMatthew G. Knepley ts->ops->snesjacobian = SNESTSFormJacobian_Mimex; 3212ffb9264SLisandro Dalcin ts->default_adapt_type = TSADAPTNONE; 322abadfa0fSMatthew G. Knepley 3239566063dSJacob Faibussowitsch PetscCall(PetscNewLog(ts, &mimex)); 324abadfa0fSMatthew G. Knepley ts->data = (void *)mimex; 325fdc0a3ceSMatthew G. Knepley 326fdc0a3ceSMatthew G. Knepley mimex->version = 1; 327abadfa0fSMatthew G. Knepley PetscFunctionReturn(0); 328abadfa0fSMatthew G. Knepley } 329