1900f6b5bSMatthew G. Knepley #include <petscconvest.h> /*I "petscconvest.h" I*/ 2900f6b5bSMatthew G. Knepley #include <petscts.h> 3*f2cacb80SMatthew G. Knepley #include <petscdm.h> 4900f6b5bSMatthew G. Knepley 5900f6b5bSMatthew G. Knepley #include <petsc/private/petscconvestimpl.h> 6900f6b5bSMatthew G. Knepley 7900f6b5bSMatthew G. Knepley static PetscErrorCode PetscConvEstSetTS_Private(PetscConvEst ce, PetscObject solver) 8900f6b5bSMatthew G. Knepley { 9900f6b5bSMatthew G. Knepley PetscClassId id; 10900f6b5bSMatthew G. Knepley PetscErrorCode ierr; 11900f6b5bSMatthew G. Knepley 12900f6b5bSMatthew G. Knepley PetscFunctionBegin; 13900f6b5bSMatthew G. Knepley ierr = PetscObjectGetClassId(ce->solver, &id);CHKERRQ(ierr); 14900f6b5bSMatthew G. Knepley if (id != TS_CLASSID) SETERRQ(PetscObjectComm((PetscObject) ce), PETSC_ERR_ARG_WRONG, "Solver was not a TS"); 15900f6b5bSMatthew G. Knepley ierr = TSGetDM((TS) ce->solver, &ce->idm);CHKERRQ(ierr); 16900f6b5bSMatthew G. Knepley PetscFunctionReturn(0); 17900f6b5bSMatthew G. Knepley } 18900f6b5bSMatthew G. Knepley 19900f6b5bSMatthew G. Knepley static PetscErrorCode PetscConvEstInitGuessTS_Private(PetscConvEst ce, PetscInt r, DM dm, Vec u) 20900f6b5bSMatthew G. Knepley { 21900f6b5bSMatthew G. Knepley PetscErrorCode ierr; 22900f6b5bSMatthew G. Knepley 23900f6b5bSMatthew G. Knepley PetscFunctionBegin; 242e61be88SMatthew G. Knepley ierr = TSComputeInitialCondition((TS) ce->solver, u);CHKERRQ(ierr); 25900f6b5bSMatthew G. Knepley PetscFunctionReturn(0); 26900f6b5bSMatthew G. Knepley } 27900f6b5bSMatthew G. Knepley 28900f6b5bSMatthew G. Knepley static PetscErrorCode PetscConvEstComputeErrorTS_Private(PetscConvEst ce, PetscInt r, DM dm, Vec u, PetscReal errors[]) 29900f6b5bSMatthew G. Knepley { 30*f2cacb80SMatthew G. Knepley TS ts = (TS) ce->solver; 31*f2cacb80SMatthew G. Knepley PetscErrorCode (*exactError)(TS, Vec, Vec); 32900f6b5bSMatthew G. Knepley PetscErrorCode ierr; 33900f6b5bSMatthew G. Knepley 34900f6b5bSMatthew G. Knepley PetscFunctionBegin; 35*f2cacb80SMatthew G. Knepley ierr = TSGetComputeExactError(ts, &exactError);CHKERRQ(ierr); 36*f2cacb80SMatthew G. Knepley if (exactError) { 37*f2cacb80SMatthew G. Knepley Vec e; 38*f2cacb80SMatthew G. Knepley PetscInt f; 39*f2cacb80SMatthew G. Knepley 40900f6b5bSMatthew G. Knepley ierr = VecDuplicate(u, &e);CHKERRQ(ierr); 41*f2cacb80SMatthew G. Knepley ierr = TSComputeExactError(ts, u, e);CHKERRQ(ierr); 42900f6b5bSMatthew G. Knepley ierr = VecNorm(e, NORM_2, errors);CHKERRQ(ierr); 43*f2cacb80SMatthew G. Knepley for (f = 1; f < ce->Nf; ++f) errors[f] = errors[0]; 44900f6b5bSMatthew G. Knepley ierr = VecDestroy(&e);CHKERRQ(ierr); 45*f2cacb80SMatthew G. Knepley } else { 46*f2cacb80SMatthew G. Knepley PetscReal t; 47*f2cacb80SMatthew G. Knepley 48*f2cacb80SMatthew G. Knepley ierr = TSGetSolveTime(ts, &t);CHKERRQ(ierr); 49*f2cacb80SMatthew G. Knepley ierr = DMComputeL2FieldDiff(dm, t, ce->exactSol, ce->ctxs, u, errors);CHKERRQ(ierr); 50*f2cacb80SMatthew G. Knepley } 51900f6b5bSMatthew G. Knepley PetscFunctionReturn(0); 52900f6b5bSMatthew G. Knepley } 53900f6b5bSMatthew G. Knepley 54900f6b5bSMatthew G. Knepley static PetscErrorCode PetscConvEstGetConvRateTS_Private(PetscConvEst ce, PetscReal alpha[]) 55900f6b5bSMatthew G. Knepley { 56900f6b5bSMatthew G. Knepley TS ts = (TS) ce->solver; 57900f6b5bSMatthew G. Knepley Vec u; 58900f6b5bSMatthew G. Knepley PetscReal *dt, *x, *y, slope, intercept; 59900f6b5bSMatthew G. Knepley PetscInt Ns, oNs, Nf = ce->Nf, f, Nr = ce->Nr, r; 60900f6b5bSMatthew G. Knepley PetscErrorCode ierr; 61900f6b5bSMatthew G. Knepley 62900f6b5bSMatthew G. Knepley PetscFunctionBegin; 63900f6b5bSMatthew G. Knepley ierr = TSGetSolution(ts, &u);CHKERRQ(ierr); 64900f6b5bSMatthew G. Knepley ierr = PetscMalloc1(Nr+1, &dt);CHKERRQ(ierr); 65900f6b5bSMatthew G. Knepley ierr = TSGetTimeStep(ts, &dt[0]);CHKERRQ(ierr); 66900f6b5bSMatthew G. Knepley ierr = TSGetMaxSteps(ts, &oNs);CHKERRQ(ierr); 67900f6b5bSMatthew G. Knepley Ns = oNs; 68900f6b5bSMatthew G. Knepley for (r = 0; r <= Nr; ++r) { 69900f6b5bSMatthew G. Knepley if (r > 0) { 702e61be88SMatthew G. Knepley dt[r] = dt[r-1]/ce->r; 712e61be88SMatthew G. Knepley Ns = PetscCeilReal(Ns*ce->r); 72900f6b5bSMatthew G. Knepley } 73900f6b5bSMatthew G. Knepley ierr = TSSetTime(ts, 0.0);CHKERRQ(ierr); 74900f6b5bSMatthew G. Knepley ierr = TSSetStepNumber(ts, 0);CHKERRQ(ierr); 75900f6b5bSMatthew G. Knepley ierr = TSSetTimeStep(ts, dt[r]);CHKERRQ(ierr); 76900f6b5bSMatthew G. Knepley ierr = TSSetMaxSteps(ts, Ns);CHKERRQ(ierr); 77900f6b5bSMatthew G. Knepley ierr = PetscConvEstComputeInitialGuess(ce, r, NULL, u);CHKERRQ(ierr); 78900f6b5bSMatthew G. Knepley ierr = TSSolve(ts, u);CHKERRQ(ierr); 79900f6b5bSMatthew G. Knepley ierr = PetscLogEventBegin(ce->event, ce, 0, 0, 0);CHKERRQ(ierr); 80*f2cacb80SMatthew G. Knepley ierr = PetscConvEstComputeError(ce, r, ce->idm, u, &ce->errors[r*Nf]);CHKERRQ(ierr); 81900f6b5bSMatthew G. Knepley ierr = PetscLogEventEnd(ce->event, ce, 0, 0, 0);CHKERRQ(ierr); 82900f6b5bSMatthew G. Knepley for (f = 0; f < ce->Nf; ++f) { 83900f6b5bSMatthew G. Knepley ierr = PetscLogEventSetDof(ce->event, f, 1.0/dt[r]);CHKERRQ(ierr); 84900f6b5bSMatthew G. Knepley ierr = PetscLogEventSetError(ce->event, f, ce->errors[r*Nf+f]);CHKERRQ(ierr); 85900f6b5bSMatthew G. Knepley } 86*f2cacb80SMatthew G. Knepley /* Monitor */ 87*f2cacb80SMatthew G. Knepley ierr = PetscConvEstMonitorDefault(ce, r);CHKERRQ(ierr); 88900f6b5bSMatthew G. Knepley } 89900f6b5bSMatthew G. Knepley /* Fit convergence rate */ 90900f6b5bSMatthew G. Knepley if (Nr) { 91900f6b5bSMatthew G. Knepley ierr = PetscMalloc2(Nr+1, &x, Nr+1, &y);CHKERRQ(ierr); 92900f6b5bSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 93900f6b5bSMatthew G. Knepley for (r = 0; r <= Nr; ++r) { 94*f2cacb80SMatthew G. Knepley x[r] = PetscLog10Real(dt[r]); 95900f6b5bSMatthew G. Knepley y[r] = PetscLog10Real(ce->errors[r*Nf+f]); 96900f6b5bSMatthew G. Knepley } 97900f6b5bSMatthew G. Knepley ierr = PetscLinearRegression(Nr+1, x, y, &slope, &intercept);CHKERRQ(ierr); 98900f6b5bSMatthew G. Knepley /* Since lg err = s lg dt + b */ 99900f6b5bSMatthew G. Knepley alpha[f] = slope; 100900f6b5bSMatthew G. Knepley } 101900f6b5bSMatthew G. Knepley ierr = PetscFree2(x, y);CHKERRQ(ierr); 102900f6b5bSMatthew G. Knepley } 103900f6b5bSMatthew G. Knepley /* Reset solver */ 104900f6b5bSMatthew G. Knepley ierr = TSSetConvergedReason(ts, TS_CONVERGED_ITERATING);CHKERRQ(ierr); 105900f6b5bSMatthew G. Knepley ierr = TSSetTime(ts, 0.0);CHKERRQ(ierr); 106900f6b5bSMatthew G. Knepley ierr = TSSetStepNumber(ts, 0);CHKERRQ(ierr); 107900f6b5bSMatthew G. Knepley ierr = TSSetTimeStep(ts, dt[0]);CHKERRQ(ierr); 108900f6b5bSMatthew G. Knepley ierr = TSSetMaxSteps(ts, oNs);CHKERRQ(ierr); 109900f6b5bSMatthew G. Knepley ierr = PetscConvEstComputeInitialGuess(ce, 0, NULL, u);CHKERRQ(ierr); 110900f6b5bSMatthew G. Knepley ierr = PetscFree(dt);CHKERRQ(ierr); 111900f6b5bSMatthew G. Knepley PetscFunctionReturn(0); 112900f6b5bSMatthew G. Knepley } 113900f6b5bSMatthew G. Knepley 114900f6b5bSMatthew G. Knepley PetscErrorCode PetscConvEstUseTS(PetscConvEst ce) 115900f6b5bSMatthew G. Knepley { 116900f6b5bSMatthew G. Knepley PetscFunctionBegin; 117900f6b5bSMatthew G. Knepley PetscValidHeaderSpecific(ce, PETSC_OBJECT_CLASSID, 1); 118900f6b5bSMatthew G. Knepley ce->ops->setsolver = PetscConvEstSetTS_Private; 119900f6b5bSMatthew G. Knepley ce->ops->initguess = PetscConvEstInitGuessTS_Private; 120900f6b5bSMatthew G. Knepley ce->ops->computeerror = PetscConvEstComputeErrorTS_Private; 121900f6b5bSMatthew G. Knepley ce->ops->getconvrate = PetscConvEstGetConvRateTS_Private; 122900f6b5bSMatthew G. Knepley PetscFunctionReturn(0); 123900f6b5bSMatthew G. Knepley } 124