16af0ca60SMatthew G. Knepley #include <petscconvest.h> /*I "petscconvest.h" I*/ 26af0ca60SMatthew G. Knepley #include <petscdmplex.h> 36af0ca60SMatthew G. Knepley #include <petscds.h> 46af0ca60SMatthew G. Knepley #include <petscblaslapack.h> 56af0ca60SMatthew G. Knepley 66af0ca60SMatthew G. Knepley #include <petsc/private/petscconvestimpl.h> 76af0ca60SMatthew G. Knepley 86af0ca60SMatthew G. Knepley static PetscErrorCode zero_private(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 96af0ca60SMatthew G. Knepley { 106af0ca60SMatthew G. Knepley PetscInt c; 116af0ca60SMatthew G. Knepley for (c = 0; c < Nc; ++c) u[c] = 0.0; 126af0ca60SMatthew G. Knepley return 0; 136af0ca60SMatthew G. Knepley } 146af0ca60SMatthew G. Knepley 156af0ca60SMatthew G. Knepley 166af0ca60SMatthew G. Knepley /*@ 176af0ca60SMatthew G. Knepley PetscConvEstCreate - Create a PetscConvEst object 186af0ca60SMatthew G. Knepley 196af0ca60SMatthew G. Knepley Collective on MPI_Comm 206af0ca60SMatthew G. Knepley 216af0ca60SMatthew G. Knepley Input Parameter: 226af0ca60SMatthew G. Knepley . comm - The communicator for the PetscConvEst object 236af0ca60SMatthew G. Knepley 246af0ca60SMatthew G. Knepley Output Parameter: 256af0ca60SMatthew G. Knepley . ce - The PetscConvEst object 266af0ca60SMatthew G. Knepley 276af0ca60SMatthew G. Knepley Level: beginner 286af0ca60SMatthew G. Knepley 296af0ca60SMatthew G. Knepley .keywords: PetscConvEst, convergence, create 306af0ca60SMatthew G. Knepley .seealso: PetscConvEstDestroy(), PetscConvEstGetConvRate() 316af0ca60SMatthew G. Knepley @*/ 326af0ca60SMatthew G. Knepley PetscErrorCode PetscConvEstCreate(MPI_Comm comm, PetscConvEst *ce) 336af0ca60SMatthew G. Knepley { 346af0ca60SMatthew G. Knepley PetscErrorCode ierr; 356af0ca60SMatthew G. Knepley 366af0ca60SMatthew G. Knepley PetscFunctionBegin; 376af0ca60SMatthew G. Knepley PetscValidPointer(ce, 2); 386af0ca60SMatthew G. Knepley ierr = PetscSysInitializePackage();CHKERRQ(ierr); 396af0ca60SMatthew G. Knepley ierr = PetscHeaderCreate(*ce, PETSC_OBJECT_CLASSID, "PetscConvEst", "ConvergenceEstimator", "SNES", comm, PetscConvEstDestroy, PetscConvEstView);CHKERRQ(ierr); 406af0ca60SMatthew G. Knepley (*ce)->monitor = PETSC_FALSE; 416af0ca60SMatthew G. Knepley (*ce)->Nr = 4; 426af0ca60SMatthew G. Knepley PetscFunctionReturn(0); 436af0ca60SMatthew G. Knepley } 446af0ca60SMatthew G. Knepley 456af0ca60SMatthew G. Knepley /*@ 466af0ca60SMatthew G. Knepley PetscConvEstDestroy - Destroys a PetscConvEst object 476af0ca60SMatthew G. Knepley 486af0ca60SMatthew G. Knepley Collective on PetscConvEst 496af0ca60SMatthew G. Knepley 506af0ca60SMatthew G. Knepley Input Parameter: 516af0ca60SMatthew G. Knepley . ce - The PetscConvEst object 526af0ca60SMatthew G. Knepley 536af0ca60SMatthew G. Knepley Level: beginner 546af0ca60SMatthew G. Knepley 556af0ca60SMatthew G. Knepley .keywords: PetscConvEst, convergence, destroy 566af0ca60SMatthew G. Knepley .seealso: PetscConvEstCreate(), PetscConvEstGetConvRate() 576af0ca60SMatthew G. Knepley @*/ 586af0ca60SMatthew G. Knepley PetscErrorCode PetscConvEstDestroy(PetscConvEst *ce) 596af0ca60SMatthew G. Knepley { 606af0ca60SMatthew G. Knepley PetscErrorCode ierr; 616af0ca60SMatthew G. Knepley 626af0ca60SMatthew G. Knepley PetscFunctionBegin; 636af0ca60SMatthew G. Knepley if (!*ce) PetscFunctionReturn(0); 646af0ca60SMatthew G. Knepley PetscValidHeaderSpecific((*ce),PETSC_OBJECT_CLASSID,1); 656af0ca60SMatthew G. Knepley if (--((PetscObject)(*ce))->refct > 0) { 666af0ca60SMatthew G. Knepley *ce = NULL; 676af0ca60SMatthew G. Knepley PetscFunctionReturn(0); 686af0ca60SMatthew G. Knepley } 696af0ca60SMatthew G. Knepley ierr = PetscFree2((*ce)->initGuess, (*ce)->exactSol);CHKERRQ(ierr); 706af0ca60SMatthew G. Knepley ierr = PetscFree((*ce)->errors);CHKERRQ(ierr); 716af0ca60SMatthew G. Knepley ierr = PetscHeaderDestroy(ce);CHKERRQ(ierr); 726af0ca60SMatthew G. Knepley PetscFunctionReturn(0); 736af0ca60SMatthew G. Knepley } 746af0ca60SMatthew G. Knepley 756af0ca60SMatthew G. Knepley /*@ 766af0ca60SMatthew G. Knepley PetscConvEstSetFromOptions - Sets a PetscConvEst object from options 776af0ca60SMatthew G. Knepley 786af0ca60SMatthew G. Knepley Collective on PetscConvEst 796af0ca60SMatthew G. Knepley 806af0ca60SMatthew G. Knepley Input Parameters: 816af0ca60SMatthew G. Knepley . ce - The PetscConvEst object 826af0ca60SMatthew G. Knepley 836af0ca60SMatthew G. Knepley Level: beginner 846af0ca60SMatthew G. Knepley 856af0ca60SMatthew G. Knepley .keywords: PetscConvEst, convergence, options 866af0ca60SMatthew G. Knepley .seealso: PetscConvEstCreate(), PetscConvEstGetConvRate() 876af0ca60SMatthew G. Knepley @*/ 886af0ca60SMatthew G. Knepley PetscErrorCode PetscConvEstSetFromOptions(PetscConvEst ce) 896af0ca60SMatthew G. Knepley { 906af0ca60SMatthew G. Knepley PetscErrorCode ierr; 916af0ca60SMatthew G. Knepley 926af0ca60SMatthew G. Knepley PetscFunctionBegin; 936af0ca60SMatthew G. Knepley ierr = PetscOptionsBegin(PetscObjectComm((PetscObject) ce), "", "Convergence Estimator Options", "PetscConvEst");CHKERRQ(ierr); 946af0ca60SMatthew G. Knepley ierr = PetscOptionsInt("-num_refine", "The number of refinements for the convergence check", "PetscConvEst", ce->Nr, &ce->Nr, NULL);CHKERRQ(ierr); 956af0ca60SMatthew G. Knepley ierr = PetscOptionsEnd(); 966af0ca60SMatthew G. Knepley PetscFunctionReturn(0); 976af0ca60SMatthew G. Knepley } 986af0ca60SMatthew G. Knepley 996af0ca60SMatthew G. Knepley /*@ 1006af0ca60SMatthew G. Knepley PetscConvEstView - Views a PetscConvEst object 1016af0ca60SMatthew G. Knepley 1026af0ca60SMatthew G. Knepley Collective on PetscConvEst 1036af0ca60SMatthew G. Knepley 1046af0ca60SMatthew G. Knepley Input Parameters: 1056af0ca60SMatthew G. Knepley + ce - The PetscConvEst object 1066af0ca60SMatthew G. Knepley - viewer - The PetscViewer object 1076af0ca60SMatthew G. Knepley 1086af0ca60SMatthew G. Knepley Level: beginner 1096af0ca60SMatthew G. Knepley 1106af0ca60SMatthew G. Knepley .keywords: PetscConvEst, convergence, view 1116af0ca60SMatthew G. Knepley .seealso: PetscConvEstCreate(), PetscConvEstGetConvRate() 1126af0ca60SMatthew G. Knepley @*/ 1136af0ca60SMatthew G. Knepley PetscErrorCode PetscConvEstView(PetscConvEst ce, PetscViewer viewer) 1146af0ca60SMatthew G. Knepley { 1156af0ca60SMatthew G. Knepley PetscErrorCode ierr; 1166af0ca60SMatthew G. Knepley 1176af0ca60SMatthew G. Knepley PetscFunctionBegin; 1186af0ca60SMatthew G. Knepley ierr = PetscObjectPrintClassNamePrefixType((PetscObject) ce, viewer);CHKERRQ(ierr); 1196af0ca60SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "ConvEst with %D levels\n", ce->Nr+1);CHKERRQ(ierr); 1206af0ca60SMatthew G. Knepley PetscFunctionReturn(0); 1216af0ca60SMatthew G. Knepley } 1226af0ca60SMatthew G. Knepley 1236af0ca60SMatthew G. Knepley /*@ 1246af0ca60SMatthew G. Knepley PetscConvEstGetSolver - Gets the solver used to produce discrete solutions 1256af0ca60SMatthew G. Knepley 1266af0ca60SMatthew G. Knepley Not collective 1276af0ca60SMatthew G. Knepley 1286af0ca60SMatthew G. Knepley Input Parameter: 1296af0ca60SMatthew G. Knepley . ce - The PetscConvEst object 1306af0ca60SMatthew G. Knepley 1316af0ca60SMatthew G. Knepley Output Parameter: 1326af0ca60SMatthew G. Knepley . snes - The solver 1336af0ca60SMatthew G. Knepley 1346af0ca60SMatthew G. Knepley Level: intermediate 1356af0ca60SMatthew G. Knepley 1366af0ca60SMatthew G. Knepley .keywords: PetscConvEst, convergence 1376af0ca60SMatthew G. Knepley .seealso: PetscConvEstSetSolver(), PetscConvEstCreate(), PetscConvEstGetConvRate() 1386af0ca60SMatthew G. Knepley @*/ 1396af0ca60SMatthew G. Knepley PetscErrorCode PetscConvEstGetSolver(PetscConvEst ce, SNES *snes) 1406af0ca60SMatthew G. Knepley { 1416af0ca60SMatthew G. Knepley PetscFunctionBegin; 1426af0ca60SMatthew G. Knepley PetscValidHeaderSpecific(ce, PETSC_OBJECT_CLASSID, 1); 1436af0ca60SMatthew G. Knepley PetscValidPointer(snes, 2); 1446af0ca60SMatthew G. Knepley *snes = ce->snes; 1456af0ca60SMatthew G. Knepley PetscFunctionReturn(0); 1466af0ca60SMatthew G. Knepley } 1476af0ca60SMatthew G. Knepley 1486af0ca60SMatthew G. Knepley /*@ 1496af0ca60SMatthew G. Knepley PetscConvEstSetSolver - Sets the solver used to produce discrete solutions 1506af0ca60SMatthew G. Knepley 1516af0ca60SMatthew G. Knepley Not collective 1526af0ca60SMatthew G. Knepley 1536af0ca60SMatthew G. Knepley Input Parameters: 1546af0ca60SMatthew G. Knepley + ce - The PetscConvEst object 1556af0ca60SMatthew G. Knepley - snes - The solver 1566af0ca60SMatthew G. Knepley 1576af0ca60SMatthew G. Knepley Level: intermediate 1586af0ca60SMatthew G. Knepley 1596af0ca60SMatthew G. Knepley Note: The solver MUST have an attached DM/DS, so that we know the exact solution 1606af0ca60SMatthew G. Knepley 1616af0ca60SMatthew G. Knepley .keywords: PetscConvEst, convergence 1626af0ca60SMatthew G. Knepley .seealso: PetscConvEstGetSolver(), PetscConvEstCreate(), PetscConvEstGetConvRate() 1636af0ca60SMatthew G. Knepley @*/ 1646af0ca60SMatthew G. Knepley PetscErrorCode PetscConvEstSetSolver(PetscConvEst ce, SNES snes) 1656af0ca60SMatthew G. Knepley { 1666af0ca60SMatthew G. Knepley PetscErrorCode ierr; 1676af0ca60SMatthew G. Knepley 1686af0ca60SMatthew G. Knepley PetscFunctionBegin; 1696af0ca60SMatthew G. Knepley PetscValidHeaderSpecific(ce, PETSC_OBJECT_CLASSID, 1); 1706af0ca60SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 2); 1716af0ca60SMatthew G. Knepley ce->snes = snes; 1726af0ca60SMatthew G. Knepley ierr = SNESGetDM(ce->snes, &ce->idm);CHKERRQ(ierr); 1736af0ca60SMatthew G. Knepley PetscFunctionReturn(0); 1746af0ca60SMatthew G. Knepley } 1756af0ca60SMatthew G. Knepley 1766af0ca60SMatthew G. Knepley /*@ 1776af0ca60SMatthew G. Knepley PetscConvEstSetUp - After the solver is specified, we create structures for estimating convergence 1786af0ca60SMatthew G. Knepley 1796af0ca60SMatthew G. Knepley Collective on PetscConvEst 1806af0ca60SMatthew G. Knepley 1816af0ca60SMatthew G. Knepley Input Parameters: 1826af0ca60SMatthew G. Knepley . ce - The PetscConvEst object 1836af0ca60SMatthew G. Knepley 1846af0ca60SMatthew G. Knepley Level: beginner 1856af0ca60SMatthew G. Knepley 1866af0ca60SMatthew G. Knepley .keywords: PetscConvEst, convergence, setup 1876af0ca60SMatthew G. Knepley .seealso: PetscConvEstCreate(), PetscConvEstGetConvRate() 1886af0ca60SMatthew G. Knepley @*/ 1890955ed61SMatthew G. Knepley PetscErrorCode PetscConvEstSetUp(PetscConvEst ce) 1906af0ca60SMatthew G. Knepley { 1916af0ca60SMatthew G. Knepley PetscDS prob; 1926af0ca60SMatthew G. Knepley PetscInt f; 1936af0ca60SMatthew G. Knepley PetscErrorCode ierr; 1946af0ca60SMatthew G. Knepley 1956af0ca60SMatthew G. Knepley PetscFunctionBegin; 1966af0ca60SMatthew G. Knepley ierr = DMGetDS(ce->idm, &prob);CHKERRQ(ierr); 1976af0ca60SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &ce->Nf);CHKERRQ(ierr); 1986af0ca60SMatthew G. Knepley ierr = PetscMalloc1((ce->Nr+1)*ce->Nf, &ce->errors);CHKERRQ(ierr); 1996af0ca60SMatthew G. Knepley ierr = PetscMalloc2(ce->Nf, &ce->initGuess, ce->Nf, &ce->exactSol);CHKERRQ(ierr); 2006af0ca60SMatthew G. Knepley for (f = 0; f < ce->Nf; ++f) ce->initGuess[f] = zero_private; 2016af0ca60SMatthew G. Knepley for (f = 0; f < ce->Nf; ++f) { 2026af0ca60SMatthew G. Knepley ierr = PetscDSGetExactSolution(prob, f, &ce->exactSol[f]);CHKERRQ(ierr); 2036af0ca60SMatthew G. Knepley if (!ce->exactSol[f]) SETERRQ1(PetscObjectComm((PetscObject) ce), PETSC_ERR_ARG_WRONG, "DS must contain exact solution functions in order to estimate convergence, missing for field %D", f); 2046af0ca60SMatthew G. Knepley } 2056af0ca60SMatthew G. Knepley PetscFunctionReturn(0); 2066af0ca60SMatthew G. Knepley } 2076af0ca60SMatthew G. Knepley 2086af0ca60SMatthew G. Knepley static PetscErrorCode PetscConvEstLinearRegression_Private(PetscConvEst ce, PetscInt n, const PetscReal x[], const PetscReal y[], PetscReal *slope, PetscReal *intercept) 2096af0ca60SMatthew G. Knepley { 21028cc7b48SMatthew G. Knepley PetscScalar H[4]; 21128cc7b48SMatthew G. Knepley PetscReal *X, *Y, beta[2]; 2126af0ca60SMatthew G. Knepley PetscInt i, j, k; 2136af0ca60SMatthew G. Knepley PetscErrorCode ierr; 2146af0ca60SMatthew G. Knepley 2156af0ca60SMatthew G. Knepley PetscFunctionBegin; 2168fa78361SMatthew G. Knepley *slope = *intercept = 0.0; 2176af0ca60SMatthew G. Knepley ierr = PetscMalloc2(n*2, &X, n*2, &Y);CHKERRQ(ierr); 2186af0ca60SMatthew G. Knepley for (k = 0; k < n; ++k) { 2196af0ca60SMatthew G. Knepley /* X[n,2] = [1, x] */ 2206af0ca60SMatthew G. Knepley X[k*2+0] = 1.0; 2216af0ca60SMatthew G. Knepley X[k*2+1] = x[k]; 2226af0ca60SMatthew G. Knepley } 2236af0ca60SMatthew G. Knepley /* H = X^T X */ 2246af0ca60SMatthew G. Knepley for (i = 0; i < 2; ++i) { 2256af0ca60SMatthew G. Knepley for (j = 0; j < 2; ++j) { 2266af0ca60SMatthew G. Knepley H[i*2+j] = 0.0; 2276af0ca60SMatthew G. Knepley for (k = 0; k < n; ++k) { 2286af0ca60SMatthew G. Knepley H[i*2+j] += X[k*2+i] * X[k*2+j]; 2296af0ca60SMatthew G. Knepley } 2306af0ca60SMatthew G. Knepley } 2316af0ca60SMatthew G. Knepley } 2326af0ca60SMatthew G. Knepley /* H = (X^T X)^{-1} */ 2336af0ca60SMatthew G. Knepley { 2346af0ca60SMatthew G. Knepley PetscBLASInt two = 2, ipiv[2], info; 2350955ed61SMatthew G. Knepley PetscScalar work[2]; 2366af0ca60SMatthew G. Knepley 2376af0ca60SMatthew G. Knepley ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2386af0ca60SMatthew G. Knepley PetscStackCallBLAS("LAPACKgetrf", LAPACKgetrf_(&two, &two, H, &two, ipiv, &info)); 2396af0ca60SMatthew G. Knepley PetscStackCallBLAS("LAPACKgetri", LAPACKgetri_(&two, H, &two, ipiv, work, &two, &info)); 2406af0ca60SMatthew G. Knepley ierr = PetscFPTrapPop();CHKERRQ(ierr); 2416af0ca60SMatthew G. Knepley } 2426af0ca60SMatthew G. Knepley /* Y = H X^T */ 2436af0ca60SMatthew G. Knepley for (i = 0; i < 2; ++i) { 2446af0ca60SMatthew G. Knepley for (k = 0; k < n; ++k) { 2456af0ca60SMatthew G. Knepley Y[i*n+k] = 0.0; 2466af0ca60SMatthew G. Knepley for (j = 0; j < 2; ++j) { 24728cc7b48SMatthew G. Knepley Y[i*n+k] += PetscRealPart(H[i*2+j]) * X[k*2+j]; 2486af0ca60SMatthew G. Knepley } 2496af0ca60SMatthew G. Knepley } 2506af0ca60SMatthew G. Knepley } 2516af0ca60SMatthew G. Knepley /* beta = Y error = [y-intercept, slope] */ 2526af0ca60SMatthew G. Knepley for (i = 0; i < 2; ++i) { 2536af0ca60SMatthew G. Knepley beta[i] = 0.0; 2546af0ca60SMatthew G. Knepley for (k = 0; k < n; ++k) { 2556af0ca60SMatthew G. Knepley beta[i] += Y[i*n+k] * y[k]; 2566af0ca60SMatthew G. Knepley } 2576af0ca60SMatthew G. Knepley } 2586af0ca60SMatthew G. Knepley ierr = PetscFree2(X, Y);CHKERRQ(ierr); 2596af0ca60SMatthew G. Knepley *intercept = beta[0]; 2606af0ca60SMatthew G. Knepley *slope = beta[1]; 2616af0ca60SMatthew G. Knepley PetscFunctionReturn(0); 2626af0ca60SMatthew G. Knepley } 2636af0ca60SMatthew G. Knepley 2646af0ca60SMatthew G. Knepley /*@ 2656af0ca60SMatthew G. Knepley PetscConvEstGetConvRate - Returns an estimate of the convergence rate for the discretization 2666af0ca60SMatthew G. Knepley 2676af0ca60SMatthew G. Knepley Not collective 2686af0ca60SMatthew G. Knepley 2696af0ca60SMatthew G. Knepley Input Parameter: 2706af0ca60SMatthew G. Knepley . ce - The PetscConvEst object 2716af0ca60SMatthew G. Knepley 2726af0ca60SMatthew G. Knepley Output Parameter: 2736af0ca60SMatthew G. Knepley . alpha - The convergence rate 2746af0ca60SMatthew G. Knepley 2756af0ca60SMatthew G. Knepley Note: The convergence rate alpha is defined by 2766af0ca60SMatthew G. Knepley $ || u_h - u_exact || < C h^alpha 2776af0ca60SMatthew G. Knepley where u_h is the discrete solution, and h is a measure of the discretization size. 2786af0ca60SMatthew G. Knepley 2796af0ca60SMatthew G. Knepley We solve a series of problems on refined meshes, calculate an error based upon the exact solution in the DS, 2806af0ca60SMatthew G. Knepley and then fit the result to our model above using linear regression. 2816af0ca60SMatthew G. Knepley 2826af0ca60SMatthew G. Knepley Options database keys: 2836af0ca60SMatthew G. Knepley . -snes_convergence_estimate : Execute convergence estimation and print out the rate 2846af0ca60SMatthew G. Knepley 2856af0ca60SMatthew G. Knepley Level: intermediate 2866af0ca60SMatthew G. Knepley 2876af0ca60SMatthew G. Knepley .keywords: PetscConvEst, convergence 2886af0ca60SMatthew G. Knepley .seealso: PetscConvEstSetSolver(), PetscConvEstCreate(), PetscConvEstGetConvRate() 2896af0ca60SMatthew G. Knepley @*/ 2906af0ca60SMatthew G. Knepley PetscErrorCode PetscConvEstGetConvRate(PetscConvEst ce, PetscReal *alpha) 2916af0ca60SMatthew G. Knepley { 2926af0ca60SMatthew G. Knepley DM *dm; 2936af0ca60SMatthew G. Knepley PetscDS prob; 2946af0ca60SMatthew G. Knepley PetscObject disc; 2956af0ca60SMatthew G. Knepley MPI_Comm comm; 2966af0ca60SMatthew G. Knepley const char *uname, *dmname; 2976af0ca60SMatthew G. Knepley void *ctx; 2986af0ca60SMatthew G. Knepley Vec u; 2996af0ca60SMatthew G. Knepley PetscReal t = 0.0, *x, *y, slope, intercept; 3006af0ca60SMatthew G. Knepley PetscInt *dof, dim, Nr = ce->Nr, r; 3016af0ca60SMatthew G. Knepley PetscErrorCode ierr; 3026af0ca60SMatthew G. Knepley 3036af0ca60SMatthew G. Knepley PetscFunctionBegin; 3046af0ca60SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) ce, &comm);CHKERRQ(ierr); 3056af0ca60SMatthew G. Knepley ierr = DMGetDimension(ce->idm, &dim);CHKERRQ(ierr); 3066af0ca60SMatthew G. Knepley ierr = DMGetApplicationContext(ce->idm, &ctx);CHKERRQ(ierr); 3076af0ca60SMatthew G. Knepley ierr = DMGetDS(ce->idm, &prob);CHKERRQ(ierr); 3086af0ca60SMatthew G. Knepley ierr = DMPlexSetRefinementUniform(ce->idm, PETSC_TRUE);CHKERRQ(ierr); 3096af0ca60SMatthew G. Knepley ierr = PetscMalloc2((Nr+1), &dm, (Nr+1), &dof);CHKERRQ(ierr); 3106af0ca60SMatthew G. Knepley dm[0] = ce->idm; 3116af0ca60SMatthew G. Knepley *alpha = 0.0; 3126af0ca60SMatthew G. Knepley /* Loop over meshes */ 3136af0ca60SMatthew G. Knepley for (r = 0; r <= Nr; ++r) { 3146af0ca60SMatthew G. Knepley if (r > 0) { 3156af0ca60SMatthew G. Knepley ierr = DMRefine(dm[r-1], MPI_COMM_NULL, &dm[r]);CHKERRQ(ierr); 3166af0ca60SMatthew G. Knepley ierr = DMSetCoarseDM(dm[r], dm[r-1]);CHKERRQ(ierr); 3176af0ca60SMatthew G. Knepley ierr = DMSetDS(dm[r], prob);CHKERRQ(ierr); 3186af0ca60SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm[r-1], &dmname);CHKERRQ(ierr); 3196af0ca60SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) dm[r], dmname);CHKERRQ(ierr); 3206af0ca60SMatthew G. Knepley } 3216af0ca60SMatthew G. Knepley ierr = DMViewFromOptions(dm[r], NULL, "-conv_dm_view");CHKERRQ(ierr); 3226af0ca60SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm[r], 0, NULL, &dof[r]);CHKERRQ(ierr); 3236af0ca60SMatthew G. Knepley /* Create solution */ 3246af0ca60SMatthew G. Knepley ierr = DMCreateGlobalVector(dm[r], &u);CHKERRQ(ierr); 325239a0881SMatthew G. Knepley ierr = PetscDSGetDiscretization(prob, 0, &disc);CHKERRQ(ierr); 326239a0881SMatthew G. Knepley ierr = PetscObjectGetName(disc, &uname);CHKERRQ(ierr); 3276af0ca60SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) u, uname);CHKERRQ(ierr); 3286af0ca60SMatthew G. Knepley /* Setup solver */ 3296af0ca60SMatthew G. Knepley ierr = SNESReset(ce->snes);CHKERRQ(ierr); 3306af0ca60SMatthew G. Knepley ierr = SNESSetDM(ce->snes, dm[r]);CHKERRQ(ierr); 3316af0ca60SMatthew G. Knepley ierr = DMPlexSetSNESLocalFEM(dm[r], ctx, ctx, ctx);CHKERRQ(ierr); 3326af0ca60SMatthew G. Knepley ierr = SNESSetFromOptions(ce->snes);CHKERRQ(ierr); 3336af0ca60SMatthew G. Knepley /* Create initial guess */ 3346af0ca60SMatthew G. Knepley ierr = DMProjectFunction(dm[r], t, ce->initGuess, NULL, INSERT_VALUES, u);CHKERRQ(ierr); 3356af0ca60SMatthew G. Knepley ierr = SNESSolve(ce->snes, NULL, u);CHKERRQ(ierr); 3366af0ca60SMatthew G. Knepley ierr = DMComputeL2FieldDiff(dm[r], t, ce->exactSol, NULL, u, &ce->errors[r*ce->Nf]);CHKERRQ(ierr); 3376af0ca60SMatthew G. Knepley /* Monitor */ 3386af0ca60SMatthew G. Knepley if (ce->monitor) { 3396af0ca60SMatthew G. Knepley PetscReal *errors = &ce->errors[r*ce->Nf]; 3406af0ca60SMatthew G. Knepley PetscInt f; 3416af0ca60SMatthew G. Knepley 3426af0ca60SMatthew G. Knepley ierr = PetscPrintf(comm, "L_2 Error: [");CHKERRQ(ierr); 3436af0ca60SMatthew G. Knepley for (f = 0; f < ce->Nf; ++f) { 3446af0ca60SMatthew G. Knepley if (f > 0) {ierr = PetscPrintf(comm, ", ");CHKERRQ(ierr);} 3456af0ca60SMatthew G. Knepley if (errors[f] < 1.0e-11) {ierr = PetscPrintf(comm, "< 1e-11");CHKERRQ(ierr);} 3466af0ca60SMatthew G. Knepley else {ierr = PetscPrintf(comm, "%g", errors[f]);CHKERRQ(ierr);} 3476af0ca60SMatthew G. Knepley } 3486af0ca60SMatthew G. Knepley ierr = PetscPrintf(comm, "]\n");CHKERRQ(ierr); 3496af0ca60SMatthew G. Knepley } 3506af0ca60SMatthew G. Knepley /* Cleanup */ 3516af0ca60SMatthew G. Knepley ierr = VecDestroy(&u);CHKERRQ(ierr); 3526af0ca60SMatthew G. Knepley } 3536af0ca60SMatthew G. Knepley for (r = 1; r <= Nr; ++r) { 3546af0ca60SMatthew G. Knepley ierr = DMDestroy(&dm[r]);CHKERRQ(ierr); 3556af0ca60SMatthew G. Knepley } 3566af0ca60SMatthew G. Knepley /* Fit convergence rate */ 3576af0ca60SMatthew G. Knepley ierr = PetscMalloc2(Nr+1, &x, Nr+1, &y);CHKERRQ(ierr); 3586af0ca60SMatthew G. Knepley for (r = 0; r <= Nr; ++r) { 3596af0ca60SMatthew G. Knepley x[r] = PetscLog10Real(dof[r]); 3606af0ca60SMatthew G. Knepley y[r] = PetscLog10Real(ce->errors[r*ce->Nf+0]); 3616af0ca60SMatthew G. Knepley } 3626af0ca60SMatthew G. Knepley ierr = PetscConvEstLinearRegression_Private(ce, Nr+1, x, y, &slope, &intercept);CHKERRQ(ierr); 3636af0ca60SMatthew G. Knepley ierr = PetscFree2(x, y);CHKERRQ(ierr); 3646af0ca60SMatthew G. Knepley /* Since h^{-dim} = N, lg err = s lg N + b = -s dim lg h + b */ 3656af0ca60SMatthew G. Knepley *alpha = -slope * dim; 3666af0ca60SMatthew G. Knepley ierr = PetscFree2(dm, dof);CHKERRQ(ierr); 367*2cae373cSMatthew G. Knepley /* Restore solver */ 368*2cae373cSMatthew G. Knepley ierr = SNESReset(ce->snes);CHKERRQ(ierr); 369*2cae373cSMatthew G. Knepley ierr = SNESSetDM(ce->snes, ce->idm);CHKERRQ(ierr); 370*2cae373cSMatthew G. Knepley ierr = DMPlexSetSNESLocalFEM(ce->idm, ctx, ctx, ctx);CHKERRQ(ierr); 371*2cae373cSMatthew G. Knepley ierr = SNESSetFromOptions(ce->snes);CHKERRQ(ierr); 3726af0ca60SMatthew G. Knepley PetscFunctionReturn(0); 3736af0ca60SMatthew G. Knepley } 3746af0ca60SMatthew G. Knepley 3756af0ca60SMatthew G. Knepley /*@ 3766af0ca60SMatthew G. Knepley PetscConvEstRateView - Displays the convergence rate to a viewer 3776af0ca60SMatthew G. Knepley 3786af0ca60SMatthew G. Knepley Collective on SNES 3796af0ca60SMatthew G. Knepley 3806af0ca60SMatthew G. Knepley Parameter: 3816af0ca60SMatthew G. Knepley + snes - iterative context obtained from SNESCreate() 3826af0ca60SMatthew G. Knepley . alpha - the convergence rate 3836af0ca60SMatthew G. Knepley - viewer - the viewer to display the reason 3846af0ca60SMatthew G. Knepley 3856af0ca60SMatthew G. Knepley Options Database Keys: 3866af0ca60SMatthew G. Knepley . -snes_convergence_estimate - print the convergence rate 3876af0ca60SMatthew G. Knepley 3886af0ca60SMatthew G. Knepley Level: developer 3896af0ca60SMatthew G. Knepley 3906af0ca60SMatthew G. Knepley .seealso: PetscConvEstGetRate() 3916af0ca60SMatthew G. Knepley @*/ 3926af0ca60SMatthew G. Knepley PetscErrorCode PetscConvEstRateView(PetscConvEst ce, PetscReal alpha, PetscViewer viewer) 3936af0ca60SMatthew G. Knepley { 3946af0ca60SMatthew G. Knepley PetscBool isAscii; 3956af0ca60SMatthew G. Knepley PetscErrorCode ierr; 3966af0ca60SMatthew G. Knepley 3976af0ca60SMatthew G. Knepley PetscFunctionBegin; 3986af0ca60SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isAscii);CHKERRQ(ierr); 3996af0ca60SMatthew G. Knepley if (isAscii) { 4006af0ca60SMatthew G. Knepley ierr = PetscViewerASCIIAddTab(viewer, ((PetscObject) ce)->tablevel);CHKERRQ(ierr); 4016af0ca60SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "L_2 convergence rate: %0.2g\n", (double) alpha);CHKERRQ(ierr); 4026af0ca60SMatthew G. Knepley ierr = PetscViewerASCIISubtractTab(viewer, ((PetscObject) ce)->tablevel);CHKERRQ(ierr); 4036af0ca60SMatthew G. Knepley } 4046af0ca60SMatthew G. Knepley PetscFunctionReturn(0); 4056af0ca60SMatthew G. Knepley } 406