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