xref: /petsc/src/ts/utils/tsconvest.c (revision f2cacb80554376ba60c1c183c00cd40ea8a0a80d)
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