xref: /petsc/src/snes/interface/snesut.c (revision 4e8208cbcbc709572b8abe32f33c78b69c819375)
1af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I   "petsc/private/snesimpl.h"   I*/
2636fd056SMatthew G. Knepley #include <petscdm.h>
3ea844a1aSMatthew Knepley #include <petscsection.h>
42e7541e6SPeter Brune #include <petscblaslapack.h>
5e7e93795SLois Curfman McInnes 
63f1db9ecSBarry Smith /*@C
7420bcc1bSBarry Smith   SNESMonitorSolution - Monitors progress of a `SNES` `SNESSolve()` by calling
8f6dfbefdSBarry Smith   `VecView()` for the approximate solution at each iteration.
93f1db9ecSBarry Smith 
10c3339decSBarry Smith   Collective
113f1db9ecSBarry Smith 
123f1db9ecSBarry Smith   Input Parameters:
13f6dfbefdSBarry Smith + snes   - the `SNES` context
143f1db9ecSBarry Smith . its    - iteration number
154b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual
16e4094ef1SJacob Faibussowitsch - vf     - a viewer
173f1db9ecSBarry Smith 
18f6dfbefdSBarry Smith   Options Database Key:
19ee32d87aSMatthew G. Knepley . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
20ee32d87aSMatthew G. Knepley 
21dc4c0fb0SBarry Smith   Level: intermediate
22dc4c0fb0SBarry Smith 
23f6dfbefdSBarry Smith   Note:
243a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
25f6dfbefdSBarry Smith   to be used during the `SNESSolve()`
263a61192cSBarry Smith 
271cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`
283f1db9ecSBarry Smith @*/
SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat * vf)29d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSolution(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
30d71ae5a4SJacob Faibussowitsch {
313f1db9ecSBarry Smith   Vec         x;
32d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
333f1db9ecSBarry Smith 
343f1db9ecSBarry Smith   PetscFunctionBegin;
354d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
369566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &x));
379566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
389566063dSJacob Faibussowitsch   PetscCall(VecView(x, viewer));
399566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
413f1db9ecSBarry Smith }
423f1db9ecSBarry Smith 
435ed2d596SBarry Smith /*@C
44420bcc1bSBarry Smith   SNESMonitorResidual - Monitors progress of a `SNESSolve()` by calling
45f6dfbefdSBarry Smith   `VecView()` for the residual at each iteration.
465ed2d596SBarry Smith 
47c3339decSBarry Smith   Collective
485ed2d596SBarry Smith 
495ed2d596SBarry Smith   Input Parameters:
50f6dfbefdSBarry Smith + snes   - the `SNES` context
515ed2d596SBarry Smith . its    - iteration number
524b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual
53e4094ef1SJacob Faibussowitsch - vf     - a viewer
545ed2d596SBarry Smith 
55f6dfbefdSBarry Smith   Options Database Key:
56ee32d87aSMatthew G. Knepley . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
57ee32d87aSMatthew G. Knepley 
585ed2d596SBarry Smith   Level: intermediate
595ed2d596SBarry Smith 
60dc4c0fb0SBarry Smith   Note:
61dc4c0fb0SBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
62dc4c0fb0SBarry Smith   to be used during the `SNES` solve.
63dc4c0fb0SBarry Smith 
641cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`, `SNESMonitor()`
655ed2d596SBarry Smith @*/
SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat * vf)66d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorResidual(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
67d71ae5a4SJacob Faibussowitsch {
685ed2d596SBarry Smith   Vec x;
695ed2d596SBarry Smith 
705ed2d596SBarry Smith   PetscFunctionBegin;
71f6dfbefdSBarry Smith   PetscValidHeaderSpecific(vf->viewer, PETSC_VIEWER_CLASSID, 4);
729566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &x, NULL, NULL));
73f6dfbefdSBarry Smith   PetscCall(PetscViewerPushFormat(vf->viewer, vf->format));
74f6dfbefdSBarry Smith   PetscCall(VecView(x, vf->viewer));
75f6dfbefdSBarry Smith   PetscCall(PetscViewerPopFormat(vf->viewer));
763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
775ed2d596SBarry Smith }
785ed2d596SBarry Smith 
79d132466eSBarry Smith /*@C
80420bcc1bSBarry Smith   SNESMonitorSolutionUpdate - Monitors progress of a `SNESSolve()` by calling
81f6dfbefdSBarry Smith   `VecView()` for the UPDATE to the solution at each iteration.
82d132466eSBarry Smith 
83c3339decSBarry Smith   Collective
84d132466eSBarry Smith 
85d132466eSBarry Smith   Input Parameters:
86f6dfbefdSBarry Smith + snes   - the `SNES` context
87d132466eSBarry Smith . its    - iteration number
884b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual
89e4094ef1SJacob Faibussowitsch - vf     - a viewer
90d132466eSBarry Smith 
91f6dfbefdSBarry Smith   Options Database Key:
92ee32d87aSMatthew G. Knepley . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
93ee32d87aSMatthew G. Knepley 
94d132466eSBarry Smith   Level: intermediate
95d132466eSBarry Smith 
96dc4c0fb0SBarry Smith   Note:
97dc4c0fb0SBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
98dc4c0fb0SBarry Smith   to be used during the `SNES` solve.
99dc4c0fb0SBarry Smith 
100e4094ef1SJacob Faibussowitsch .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`, `SNESMonitor()`
101d132466eSBarry Smith @*/
SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat * vf)102d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSolutionUpdate(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
103d71ae5a4SJacob Faibussowitsch {
104d132466eSBarry Smith   Vec         x;
105d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
106d132466eSBarry Smith 
107d132466eSBarry Smith   PetscFunctionBegin;
1084d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
1099566063dSJacob Faibussowitsch   PetscCall(SNESGetSolutionUpdate(snes, &x));
1109566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
1119566063dSJacob Faibussowitsch   PetscCall(VecView(x, viewer));
1129566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
1133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
114d132466eSBarry Smith }
115d132466eSBarry Smith 
116798534f6SMatthew G. Knepley #include <petscdraw.h>
117a5c2985bSBarry Smith 
118798534f6SMatthew G. Knepley /*@C
119420bcc1bSBarry Smith   KSPMonitorSNESResidual - Prints the `SNES` residual norm, as well as the `KSP` residual norm, at each iteration of a `KSPSolve()` called within a `SNESSolve()`.
120798534f6SMatthew G. Knepley 
121c3339decSBarry Smith   Collective
122a5c2985bSBarry Smith 
123a5c2985bSBarry Smith   Input Parameters:
124a5c2985bSBarry Smith + ksp   - iterative context
125a5c2985bSBarry Smith . n     - iteration number
126a5c2985bSBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated).
127798534f6SMatthew G. Knepley - vf    - The viewer context
128798534f6SMatthew G. Knepley 
129798534f6SMatthew G. Knepley   Options Database Key:
130f6dfbefdSBarry Smith . -snes_monitor_ksp - Activates `KSPMonitorSNESResidual()`
131a5c2985bSBarry Smith 
132a5c2985bSBarry Smith   Level: intermediate
133a5c2985bSBarry Smith 
134dc4c0fb0SBarry Smith   Note:
135dc4c0fb0SBarry Smith   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
136dc4c0fb0SBarry Smith   to be used during the `KSP` solve.
137dc4c0fb0SBarry Smith 
138420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`, `KSPMonitor()`, `SNESMonitor()`, `PetscViewerAndFormat()`
139a5c2985bSBarry Smith @*/
KSPMonitorSNESResidual(KSP ksp,PetscInt n,PetscReal rnorm,PetscViewerAndFormat * vf)140d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPMonitorSNESResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
141d71ae5a4SJacob Faibussowitsch {
142798534f6SMatthew G. Knepley   PetscViewer       viewer = vf->viewer;
143798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
144798534f6SMatthew G. Knepley   SNES              snes   = (SNES)vf->data;
145a5c2985bSBarry Smith   Vec               snes_solution, work1, work2;
146a5c2985bSBarry Smith   PetscReal         snorm;
147798534f6SMatthew G. Knepley   PetscInt          tablevel;
148798534f6SMatthew G. Knepley   const char       *prefix;
149a5c2985bSBarry Smith 
150a5c2985bSBarry Smith   PetscFunctionBegin;
151798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
1529566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &snes_solution));
1539566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work1));
1549566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work2));
1559566063dSJacob Faibussowitsch   PetscCall(KSPBuildSolution(ksp, work1, NULL));
1569566063dSJacob Faibussowitsch   PetscCall(VecAYPX(work1, -1.0, snes_solution));
1579566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, work1, work2));
1589566063dSJacob Faibussowitsch   PetscCall(VecNorm(work2, NORM_2, &snorm));
1599566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work1));
1609566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work2));
161a5c2985bSBarry Smith 
1629566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
1639566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
1649566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
1659566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
1669566063dSJacob Faibussowitsch   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
16763a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Residual norm %5.3e KSP Residual norm %5.3e\n", n, (double)snorm, (double)rnorm));
1689566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
1699566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
1703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
171a5c2985bSBarry Smith }
172a5c2985bSBarry Smith 
173e5f7ee39SBarry Smith /*@C
174420bcc1bSBarry Smith   KSPMonitorSNESResidualDrawLG - Plots the linear `KSP` residual norm and the `SNES` residual norm of a `KSPSolve()` called within a `SNESSolve()`.
175e5f7ee39SBarry Smith 
176c3339decSBarry Smith   Collective
177e5f7ee39SBarry Smith 
178e5f7ee39SBarry Smith   Input Parameters:
179798534f6SMatthew G. Knepley + ksp   - iterative context
180798534f6SMatthew G. Knepley . n     - iteration number
181798534f6SMatthew G. Knepley . rnorm - 2-norm (preconditioned) residual value (may be estimated).
182f6dfbefdSBarry Smith - vf    - The viewer context, created with `KSPMonitorSNESResidualDrawLGCreate()`
183e5f7ee39SBarry Smith 
184e5f7ee39SBarry Smith   Options Database Key:
185f6dfbefdSBarry Smith . -snes_monitor_ksp draw::draw_lg - Activates `KSPMonitorSNESResidualDrawLG()`
186e5f7ee39SBarry Smith 
187dc4c0fb0SBarry Smith   Level: intermediate
188dc4c0fb0SBarry Smith 
189f6dfbefdSBarry Smith   Note:
1903a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
191f6dfbefdSBarry Smith   to be used during the `SNESSolve()`
1923a61192cSBarry Smith 
1931cc06b55SBarry Smith .seealso: [](ch_snes), `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `SNESMonitor()`, `KSPMonitor()`, `KSPMonitorSNESResidualDrawLGCreate()`
194e5f7ee39SBarry Smith @*/
KSPMonitorSNESResidualDrawLG(KSP ksp,PetscInt n,PetscReal rnorm,PetscViewerAndFormat * vf)195d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPMonitorSNESResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
196d71ae5a4SJacob Faibussowitsch {
197798534f6SMatthew G. Knepley   PetscViewer        viewer = vf->viewer;
198798534f6SMatthew G. Knepley   PetscViewerFormat  format = vf->format;
199ce78bad3SBarry Smith   PetscDrawLG        lg;
200798534f6SMatthew G. Knepley   SNES               snes = (SNES)vf->data;
201e5f7ee39SBarry Smith   Vec                snes_solution, work1, work2;
202798534f6SMatthew G. Knepley   PetscReal          snorm;
203798534f6SMatthew G. Knepley   KSPConvergedReason reason;
204798534f6SMatthew G. Knepley   PetscReal          x[2], y[2];
205e5f7ee39SBarry Smith 
206e5f7ee39SBarry Smith   PetscFunctionBegin;
207798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
208ce78bad3SBarry Smith   PetscCall(PetscViewerDrawGetDrawLG(viewer, 0, &lg));
2099566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &snes_solution));
2109566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work1));
2119566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work2));
2129566063dSJacob Faibussowitsch   PetscCall(KSPBuildSolution(ksp, work1, NULL));
2139566063dSJacob Faibussowitsch   PetscCall(VecAYPX(work1, -1.0, snes_solution));
2149566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, work1, work2));
2159566063dSJacob Faibussowitsch   PetscCall(VecNorm(work2, NORM_2, &snorm));
2169566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work1));
2179566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work2));
218e5f7ee39SBarry Smith 
2199566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
2209566063dSJacob Faibussowitsch   if (!n) PetscCall(PetscDrawLGReset(lg));
221798534f6SMatthew G. Knepley   x[0] = (PetscReal)n;
222798534f6SMatthew G. Knepley   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
223798534f6SMatthew G. Knepley   else y[0] = -15.0;
224798534f6SMatthew G. Knepley   x[1] = (PetscReal)n;
225798534f6SMatthew G. Knepley   if (snorm > 0.0) y[1] = PetscLog10Real(snorm);
226798534f6SMatthew G. Knepley   else y[1] = -15.0;
2279566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(lg, x, y));
2289566063dSJacob Faibussowitsch   PetscCall(KSPGetConvergedReason(ksp, &reason));
229798534f6SMatthew G. Knepley   if (n <= 20 || !(n % 5) || reason) {
2309566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
2319566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
232e5f7ee39SBarry Smith   }
2339566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
2343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
235e5f7ee39SBarry Smith }
236e5f7ee39SBarry Smith 
237798534f6SMatthew G. Knepley /*@C
238f6dfbefdSBarry Smith   KSPMonitorSNESResidualDrawLGCreate - Creates the `PetscViewer` used by `KSPMonitorSNESResidualDrawLG()`
239e5f7ee39SBarry Smith 
240c3339decSBarry Smith   Collective
241e5f7ee39SBarry Smith 
242798534f6SMatthew G. Knepley   Input Parameters:
243dc4c0fb0SBarry Smith + viewer - The `PetscViewer`
244798534f6SMatthew G. Knepley . format - The viewer format
245798534f6SMatthew G. Knepley - ctx    - An optional user context
246798534f6SMatthew G. Knepley 
247798534f6SMatthew G. Knepley   Output Parameter:
248798534f6SMatthew G. Knepley . vf - The viewer context
249e5f7ee39SBarry Smith 
250e5f7ee39SBarry Smith   Level: intermediate
251e5f7ee39SBarry Smith 
2521cc06b55SBarry Smith .seealso: [](ch_snes), `KSP`, `SNES`, `PetscViewerFormat`, `PetscViewerAndFormat`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
253e5f7ee39SBarry Smith @*/
KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,PetscCtx ctx,PetscViewerAndFormat ** vf)254*2a8381b2SBarry Smith PetscErrorCode KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, PetscCtx ctx, PetscViewerAndFormat **vf)
255d71ae5a4SJacob Faibussowitsch {
256798534f6SMatthew G. Knepley   const char *names[] = {"linear", "nonlinear"};
257e5f7ee39SBarry Smith 
258e5f7ee39SBarry Smith   PetscFunctionBegin;
2599566063dSJacob Faibussowitsch   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
260798534f6SMatthew G. Knepley   (*vf)->data = ctx;
261ce78bad3SBarry Smith   PetscCall(PetscViewerMonitorLGSetUp(viewer, NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300));
2623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
263e5f7ee39SBarry Smith }
264e5f7ee39SBarry Smith 
SNESMonitorDefaultSetUp(SNES snes,PetscViewerAndFormat * vf)265d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefaultSetUp(SNES snes, PetscViewerAndFormat *vf)
266d71ae5a4SJacob Faibussowitsch {
267fbcc4530SMatthew G. Knepley   PetscFunctionBegin;
268ce78bad3SBarry Smith   if (vf->format == PETSC_VIEWER_DRAW_LG) PetscCall(PetscViewerMonitorLGSetUp(vf->viewer, NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300));
2693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
270fbcc4530SMatthew G. Knepley }
271fbcc4530SMatthew G. Knepley 
2724b828684SBarry Smith /*@C
273420bcc1bSBarry Smith   SNESMonitorDefault - Monitors progress of a `SNESSolve()` (default).
274e7e93795SLois Curfman McInnes 
275c3339decSBarry Smith   Collective
276c7afd0dbSLois Curfman McInnes 
277e7e93795SLois Curfman McInnes   Input Parameters:
278f6dfbefdSBarry Smith + snes   - the `SNES` context
279e7e93795SLois Curfman McInnes . its    - iteration number
2804b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual
281d43b4f6eSBarry Smith - vf     - viewer and format structure
282fee21e36SBarry Smith 
2833c7db156SBarry Smith   Options Database Key:
2843a61192cSBarry Smith . -snes_monitor - use this function to monitor the convergence of the nonlinear solver
2853a61192cSBarry Smith 
286dc4c0fb0SBarry Smith   Level: intermediate
287dc4c0fb0SBarry Smith 
288e7e93795SLois Curfman McInnes   Notes:
289420bcc1bSBarry Smith   Prints the residual norm at each iteration.
290e7e93795SLois Curfman McInnes 
2913a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
292f6dfbefdSBarry Smith   to be used during the `SNES` solve.
2933a61192cSBarry Smith 
294e4094ef1SJacob Faibussowitsch .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorFunction()`, `SNESMonitorResidual()`,
29542747ad1SJacob Faibussowitsch           `SNESMonitorSolutionUpdate()`, `SNESMonitorScaling()`, `SNESMonitorRange()`, `SNESMonitorRatio()`,
2962fe279fdSBarry Smith           `SNESMonitorDefaultField()`, `PetscViewerFormat`, `PetscViewerAndFormat`
297e7e93795SLois Curfman McInnes @*/
SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat * vf)298d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefault(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
299d71ae5a4SJacob Faibussowitsch {
300d43b4f6eSBarry Smith   PetscViewer       viewer = vf->viewer;
301798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
302798534f6SMatthew G. Knepley   PetscBool         isascii, isdraw;
303d132466eSBarry Smith 
3043a40ed3dSBarry Smith   PetscFunctionBegin;
3054d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
3069566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
3079566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
3089566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
309798534f6SMatthew G. Knepley   if (isascii) {
3109566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
3119814a27eSStefano Zampini     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
3129814a27eSStefano Zampini       Vec              dx;
3139814a27eSStefano Zampini       PetscReal        upnorm;
3146b72add0SBarry Smith       SNESObjectiveFn *objective;
3159814a27eSStefano Zampini 
3169814a27eSStefano Zampini       PetscCall(SNESGetSolutionUpdate(snes, &dx));
3179814a27eSStefano Zampini       PetscCall(VecNorm(dx, NORM_2, &upnorm));
3189814a27eSStefano Zampini       PetscCall(SNESGetObjective(snes, &objective, NULL));
3199814a27eSStefano Zampini       if (objective) {
3209814a27eSStefano Zampini         Vec       x;
3219814a27eSStefano Zampini         PetscReal obj;
3229814a27eSStefano Zampini 
3239814a27eSStefano Zampini         PetscCall(SNESGetSolution(snes, &x));
3249814a27eSStefano Zampini         PetscCall(SNESComputeObjective(snes, x, &obj));
3259814a27eSStefano Zampini         PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e, Update norm %14.12e, Objective %14.12e\n", its, (double)fgnorm, (double)upnorm, (double)obj));
3269814a27eSStefano Zampini       } else {
3279814a27eSStefano Zampini         PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e, Update norm %14.12e\n", its, (double)fgnorm, (double)upnorm));
3289814a27eSStefano Zampini       }
3299814a27eSStefano Zampini     } else {
33063a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e\n", its, (double)fgnorm));
3319814a27eSStefano Zampini     }
3329566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
333798534f6SMatthew G. Knepley   } else if (isdraw) {
334798534f6SMatthew G. Knepley     if (format == PETSC_VIEWER_DRAW_LG) {
335ce78bad3SBarry Smith       PetscDrawLG lg;
336798534f6SMatthew G. Knepley       PetscReal   x, y;
337798534f6SMatthew G. Knepley 
338ce78bad3SBarry Smith       PetscCall(PetscViewerDrawGetDrawLG(viewer, 0, &lg));
3399566063dSJacob Faibussowitsch       if (!its) PetscCall(PetscDrawLGReset(lg));
340798534f6SMatthew G. Knepley       x = (PetscReal)its;
341798534f6SMatthew G. Knepley       if (fgnorm > 0.0) y = PetscLog10Real(fgnorm);
342798534f6SMatthew G. Knepley       else y = -15.0;
3439566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
344798534f6SMatthew G. Knepley       if (its <= 20 || !(its % 5) || snes->reason) {
3459566063dSJacob Faibussowitsch         PetscCall(PetscDrawLGDraw(lg));
3469566063dSJacob Faibussowitsch         PetscCall(PetscDrawLGSave(lg));
347798534f6SMatthew G. Knepley       }
348798534f6SMatthew G. Knepley     }
349798534f6SMatthew G. Knepley   }
3509566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
3513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
352e7e93795SLois Curfman McInnes }
3533f1db9ecSBarry Smith 
3541f60017eSBarry Smith /*@C
355420bcc1bSBarry Smith   SNESMonitorScaling - Monitors the largest value in each row of the Jacobian of a `SNESSolve()`
3561f60017eSBarry Smith 
357c3339decSBarry Smith   Collective
3581f60017eSBarry Smith 
3591f60017eSBarry Smith   Input Parameters:
360f6dfbefdSBarry Smith + snes   - the `SNES` context
3611f60017eSBarry Smith . its    - iteration number
3621f60017eSBarry Smith . fgnorm - 2-norm of residual
3631f60017eSBarry Smith - vf     - viewer and format structure
3641f60017eSBarry Smith 
365dc4c0fb0SBarry Smith   Level: intermediate
366dc4c0fb0SBarry Smith 
3671f60017eSBarry Smith   Notes:
3681f60017eSBarry Smith   This routine prints the largest value in each row of the Jacobian
3691f60017eSBarry Smith 
3703a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
371f6dfbefdSBarry Smith   to be used during the `SNES` solve.
3723a61192cSBarry Smith 
3731cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRange()`, `SNESMonitorJacUpdateSpectrum()`,
3742fe279fdSBarry Smith           `PetscViewerFormat`, `PetscViewerAndFormat`
3751f60017eSBarry Smith @*/
SNESMonitorScaling(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat * vf)376d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorScaling(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
377d71ae5a4SJacob Faibussowitsch {
3781f60017eSBarry Smith   PetscViewer viewer = vf->viewer;
3791f60017eSBarry Smith   KSP         ksp;
3801f60017eSBarry Smith   Mat         J;
3811f60017eSBarry Smith   Vec         v;
3821f60017eSBarry Smith 
3831f60017eSBarry Smith   PetscFunctionBegin;
3841f60017eSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
3859566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, &ksp));
3869566063dSJacob Faibussowitsch   PetscCall(KSPGetOperators(ksp, &J, NULL));
3879566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(J, &v, NULL));
3889566063dSJacob Faibussowitsch   PetscCall(MatGetRowMaxAbs(J, v, NULL));
3899566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
3909566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
39163a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "SNES Jacobian maximum row entries\n"));
3929566063dSJacob Faibussowitsch   PetscCall(VecView(v, viewer));
3939566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
3949566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
3959566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&v));
3963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3971f60017eSBarry Smith }
3981f60017eSBarry Smith 
399f6dfbefdSBarry Smith /*@C
400420bcc1bSBarry Smith   SNESMonitorJacUpdateSpectrum - Monitors the spectrun of the change in the Jacobian from the last Jacobian evaluation of a `SNESSolve()`
401f6dfbefdSBarry Smith 
402c3339decSBarry Smith   Collective
403f6dfbefdSBarry Smith 
404f6dfbefdSBarry Smith   Input Parameters:
405f6dfbefdSBarry Smith + snes  - the `SNES` context
406e4094ef1SJacob Faibussowitsch . it    - iteration number
407e4094ef1SJacob Faibussowitsch . fnorm - 2-norm of residual
408f6dfbefdSBarry Smith - vf    - viewer and format structure
409f6dfbefdSBarry Smith 
4102fe279fdSBarry Smith   Options Database Key:
411f6dfbefdSBarry Smith . -snes_monitor_jacupdate_spectrum - activates this monitor
412f6dfbefdSBarry Smith 
413dc4c0fb0SBarry Smith   Level: intermediate
414dc4c0fb0SBarry Smith 
415f6dfbefdSBarry Smith   Notes:
416f6dfbefdSBarry Smith   This routine prints the eigenvalues of the difference in the Jacobians
417f6dfbefdSBarry Smith 
418f6dfbefdSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
419f6dfbefdSBarry Smith   to be used during the `SNES` solve.
420f6dfbefdSBarry Smith 
4211cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRange()`, `PetscViewerFormat`, `PetscViewerAndFormat`
422f6dfbefdSBarry Smith @*/
SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,PetscViewerAndFormat * vf)423d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes, PetscInt it, PetscReal fnorm, PetscViewerAndFormat *vf)
424d71ae5a4SJacob Faibussowitsch {
4252e7541e6SPeter Brune   Vec X;
4262e7541e6SPeter Brune   Mat J, dJ, dJdense;
427d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES, Vec, Mat, Mat, void *);
4282f96bde4SJose E. Roman   PetscInt     n;
42923fff9afSBarry Smith   PetscBLASInt nb = 0, lwork;
4302e7541e6SPeter Brune   PetscReal   *eigr, *eigi;
4312e7541e6SPeter Brune   PetscScalar *work;
4322e7541e6SPeter Brune   PetscScalar *a;
4332e7541e6SPeter Brune 
4342e7541e6SPeter Brune   PetscFunctionBegin;
4353ba16761SJacob Faibussowitsch   if (it == 0) PetscFunctionReturn(PETSC_SUCCESS);
436f6dfbefdSBarry Smith   /* create the difference between the current update and the current Jacobian */
4379566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &X));
4389566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(snes, NULL, &J, &func, NULL));
4399566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(J, MAT_COPY_VALUES, &dJ));
4409566063dSJacob Faibussowitsch   PetscCall(SNESComputeJacobian(snes, X, dJ, dJ));
4419566063dSJacob Faibussowitsch   PetscCall(MatAXPY(dJ, -1.0, J, SAME_NONZERO_PATTERN));
442f5af7f23SKarl Rupp 
4432e7541e6SPeter Brune   /* compute the spectrum directly */
4449566063dSJacob Faibussowitsch   PetscCall(MatConvert(dJ, MATSEQDENSE, MAT_INITIAL_MATRIX, &dJdense));
4459566063dSJacob Faibussowitsch   PetscCall(MatGetSize(dJ, &n, NULL));
4469566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nb));
4472e7541e6SPeter Brune   lwork = 3 * nb;
4489566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &eigr));
4499566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &eigi));
4509566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lwork, &work));
4519566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(dJdense, &a));
4522e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
4532e7541e6SPeter Brune   {
4542e7541e6SPeter Brune     PetscBLASInt lierr;
4552f96bde4SJose E. Roman     PetscInt     i;
4569566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
457792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeev", LAPACKgeev_("N", "N", &nb, a, &nb, eigr, eigi, NULL, &nb, NULL, &nb, work, &lwork, &lierr));
45863a3b9bcSJacob Faibussowitsch     PetscCheck(!lierr, PETSC_COMM_SELF, PETSC_ERR_LIB, "geev() error %" PetscBLASInt_FMT, lierr);
4599566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
46063a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Eigenvalues of J_%" PetscInt_FMT " - J_%" PetscInt_FMT ":\n", it, it - 1));
46148a46eb9SPierre Jolivet     for (i = 0; i < n; i++) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "%5" PetscInt_FMT ": %20.5g + %20.5gi\n", i, (double)eigr[i], (double)eigi[i]));
4622f96bde4SJose E. Roman   }
4639566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(dJdense, &a));
4649566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&dJ));
4659566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&dJdense));
4669566063dSJacob Faibussowitsch   PetscCall(PetscFree(eigr));
4679566063dSJacob Faibussowitsch   PetscCall(PetscFree(eigi));
4689566063dSJacob Faibussowitsch   PetscCall(PetscFree(work));
4693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4702f96bde4SJose E. Roman #else
4712f96bde4SJose E. Roman   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not coded for complex");
4722f96bde4SJose E. Roman #endif
4732e7541e6SPeter Brune }
4742e7541e6SPeter Brune 
4756ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *);
4766ba87a44SLisandro Dalcin 
SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal * per)477d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRange_Private(SNES snes, PetscInt it, PetscReal *per)
478d71ae5a4SJacob Faibussowitsch {
479b271bb04SBarry Smith   Vec          resid;
480b271bb04SBarry Smith   PetscReal    rmax, pwork;
481b271bb04SBarry Smith   PetscInt     i, n, N;
482b271bb04SBarry Smith   PetscScalar *r;
483b271bb04SBarry Smith 
484b271bb04SBarry Smith   PetscFunctionBegin;
4859566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &resid, NULL, NULL));
4869566063dSJacob Faibussowitsch   PetscCall(VecNorm(resid, NORM_INFINITY, &rmax));
4879566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(resid, &n));
4889566063dSJacob Faibussowitsch   PetscCall(VecGetSize(resid, &N));
4899566063dSJacob Faibussowitsch   PetscCall(VecGetArray(resid, &r));
490b271bb04SBarry Smith   pwork = 0.0;
491ad540459SPierre Jolivet   for (i = 0; i < n; i++) pwork += (PetscAbsScalar(r[i]) > .20 * rmax);
492462c564dSBarry Smith   PetscCallMPI(MPIU_Allreduce(&pwork, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)snes)));
4939566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(resid, &r));
494b271bb04SBarry Smith   *per = *per / N;
4953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
496b271bb04SBarry Smith }
497b271bb04SBarry Smith 
498b271bb04SBarry Smith /*@C
499420bcc1bSBarry Smith   SNESMonitorRange - Prints the percentage of residual elements that are more than 10 percent of the maximum entry in the residual in each iteration of a `SNESSolve()`
500b271bb04SBarry Smith 
501c3339decSBarry Smith   Collective
502b271bb04SBarry Smith 
503b271bb04SBarry Smith   Input Parameters:
504420bcc1bSBarry Smith + snes  - `SNES` iterative context
505b271bb04SBarry Smith . it    - iteration number
506b271bb04SBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated).
507e4094ef1SJacob Faibussowitsch - vf    - unused monitor context
508b271bb04SBarry Smith 
509b271bb04SBarry Smith   Options Database Key:
510f6dfbefdSBarry Smith . -snes_monitor_range - Activates `SNESMonitorRange()`
511b271bb04SBarry Smith 
512dc4c0fb0SBarry Smith   Level: intermediate
513dc4c0fb0SBarry Smith 
514f6dfbefdSBarry Smith   Note:
5153a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
516f6dfbefdSBarry Smith   to be used during the `SNES` solve.
5173a61192cSBarry Smith 
5181cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorDefault()`, `SNESMonitorLGCreate()`, `SNESMonitorScaling()`, `PetscViewerFormat`, `PetscViewerAndFormat`
519b271bb04SBarry Smith @*/
SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,PetscViewerAndFormat * vf)520d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRange(SNES snes, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf)
521d71ae5a4SJacob Faibussowitsch {
522b271bb04SBarry Smith   PetscReal   perc, rel;
523d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
524b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
525b271bb04SBarry Smith   static PetscReal prev;
526b271bb04SBarry Smith 
527b271bb04SBarry Smith   PetscFunctionBegin;
5284d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
529b271bb04SBarry Smith   if (!it) prev = rnorm;
5309566063dSJacob Faibussowitsch   PetscCall(SNESMonitorRange_Private(snes, it, &perc));
531b271bb04SBarry Smith 
532b271bb04SBarry Smith   rel  = (prev - rnorm) / prev;
533b271bb04SBarry Smith   prev = rnorm;
5349566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
5359566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
536835f2295SStefano Zampini   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES preconditioned resid norm %14.12e Percent values above 20 percent of maximum %5.2g relative decrease %5.2e ratio %5.2e\n", it, (double)rnorm, (double)(100 * perc), (double)rel, (double)(rel / perc)));
5379566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
5389566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
5393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
540b271bb04SBarry Smith }
541b271bb04SBarry Smith 
5423a7fca6bSBarry Smith /*@C
543420bcc1bSBarry Smith   SNESMonitorRatio - Monitors progress of a `SNESSolve()` by printing the ratio of residual norm at each iteration to the previous.
5443a7fca6bSBarry Smith 
545c3339decSBarry Smith   Collective
5463a7fca6bSBarry Smith 
5473a7fca6bSBarry Smith   Input Parameters:
548f6dfbefdSBarry Smith + snes   - the `SNES` context
5493a7fca6bSBarry Smith . its    - iteration number
5503a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient)
551e4094ef1SJacob Faibussowitsch - vf     - context of monitor
5523a7fca6bSBarry Smith 
5532fe279fdSBarry Smith   Options Database Key:
554f6dfbefdSBarry Smith . -snes_monitor_ratio - activate this monitor
555f6dfbefdSBarry Smith 
5563a7fca6bSBarry Smith   Level: intermediate
5573a7fca6bSBarry Smith 
55895452b02SPatrick Sanan   Notes:
5593a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
560f6dfbefdSBarry Smith   to be used during the `SNES` solve.
5613a61192cSBarry Smith 
562f6dfbefdSBarry Smith   Be sure to call `SNESMonitorRationSetUp()` before using this monitor.
5633a61192cSBarry Smith 
5641cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorRationSetUp()`, `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `PetscViewerFormat`, `PetscViewerAndFormat`
5653a7fca6bSBarry Smith @*/
SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat * vf)566d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRatio(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
567d71ae5a4SJacob Faibussowitsch {
56877431f27SBarry Smith   PetscInt    len;
56987828ca2SBarry Smith   PetscReal  *history;
570d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
5713a7fca6bSBarry Smith 
5723a7fca6bSBarry Smith   PetscFunctionBegin;
5739566063dSJacob Faibussowitsch   PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, &len));
5749566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
5759566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
576958c9bccSBarry Smith   if (!its || !history || its > len) {
57763a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e\n", its, (double)fgnorm));
5783a7fca6bSBarry Smith   } else {
57987828ca2SBarry Smith     PetscReal ratio = fgnorm / history[its - 1];
58063a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e %14.12e\n", its, (double)fgnorm, (double)ratio));
5813a7fca6bSBarry Smith   }
5829566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
5839566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
5843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5853a7fca6bSBarry Smith }
5863a7fca6bSBarry Smith 
5873a7fca6bSBarry Smith /*@C
588f6dfbefdSBarry Smith   SNESMonitorRatioSetUp - Insures the `SNES` object is saving its history since this monitor needs access to it
5893a7fca6bSBarry Smith 
590c3339decSBarry Smith   Collective
5913a7fca6bSBarry Smith 
5923a7fca6bSBarry Smith   Input Parameters:
593f6dfbefdSBarry Smith + snes - the `SNES` context
594420bcc1bSBarry Smith - vf   - `PetscViewerAndFormat` (ignored)
5953a7fca6bSBarry Smith 
5963a7fca6bSBarry Smith   Level: intermediate
5973a7fca6bSBarry Smith 
5981cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `SNESMonitorRatio()`, `PetscViewerFormat`, `PetscViewerAndFormat`
5993a7fca6bSBarry Smith @*/
SNESMonitorRatioSetUp(SNES snes,PetscViewerAndFormat * vf)600d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRatioSetUp(SNES snes, PetscViewerAndFormat *vf)
601d71ae5a4SJacob Faibussowitsch {
60287828ca2SBarry Smith   PetscReal *history;
6033a7fca6bSBarry Smith 
6043a7fca6bSBarry Smith   PetscFunctionBegin;
6059566063dSJacob Faibussowitsch   PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, NULL));
60648a46eb9SPierre Jolivet   if (!history) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, 100, PETSC_TRUE));
6073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6083a7fca6bSBarry Smith }
6093a7fca6bSBarry Smith 
610be1f7002SBarry Smith /*
611a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
612be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
613be1f7002SBarry Smith   This is because the later digits are meaningless and are often
614be1f7002SBarry Smith   different on different machines; by using this routine different
615be1f7002SBarry Smith   machines will usually generate the same output.
616dec21524SBarry Smith 
617dec21524SBarry Smith   Deprecated: Intentionally has no manual page
618be1f7002SBarry Smith */
SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat * vf)619d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefaultShort(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
620d71ae5a4SJacob Faibussowitsch {
621d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
622d132466eSBarry Smith 
6233a40ed3dSBarry Smith   PetscFunctionBegin;
6244d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
6259566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
6269566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
6278f240d10SBarry Smith   if (fgnorm > 1.e-9) {
62863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %g\n", its, (double)fgnorm));
6293a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
63063a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %5.3e\n", its, (double)fgnorm));
6313a40ed3dSBarry Smith   } else {
63263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm < 1.e-11\n", its));
633a34d58ebSBarry Smith   }
6349566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
6359566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
6363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
637e7e93795SLois Curfman McInnes }
6382db13446SMatthew G. Knepley 
6392db13446SMatthew G. Knepley /*@C
640420bcc1bSBarry Smith   SNESMonitorDefaultField - Monitors progress of a `SNESSolve()`, separated into fields.
6412db13446SMatthew G. Knepley 
642c3339decSBarry Smith   Collective
6432db13446SMatthew G. Knepley 
6442db13446SMatthew G. Knepley   Input Parameters:
645f6dfbefdSBarry Smith + snes   - the `SNES` context
6462db13446SMatthew G. Knepley . its    - iteration number
6472db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
648e4094ef1SJacob Faibussowitsch - vf     - the PetscViewer
6492db13446SMatthew G. Knepley 
6502fe279fdSBarry Smith   Options Database Key:
651f6dfbefdSBarry Smith . -snes_monitor_field - activate this monitor
652f6dfbefdSBarry Smith 
653dc4c0fb0SBarry Smith   Level: intermediate
654dc4c0fb0SBarry Smith 
6552db13446SMatthew G. Knepley   Notes:
656f6dfbefdSBarry Smith   This routine uses the `DM` attached to the residual vector to define the fields.
6573a61192cSBarry Smith 
6583a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
659f6dfbefdSBarry Smith   to be used during the `SNES` solve.
6602db13446SMatthew G. Knepley 
6611cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `PetscViewerFormat`, `PetscViewerAndFormat`
6622db13446SMatthew G. Knepley @*/
SNESMonitorDefaultField(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat * vf)663d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
664d71ae5a4SJacob Faibussowitsch {
665d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
6662db13446SMatthew G. Knepley   Vec         r;
6672db13446SMatthew G. Knepley   DM          dm;
6682db13446SMatthew G. Knepley   PetscReal   res[256];
6692db13446SMatthew G. Knepley   PetscInt    tablevel;
6702db13446SMatthew G. Knepley 
6712db13446SMatthew G. Knepley   PetscFunctionBegin;
6724d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
6739566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &r, NULL, NULL));
6749566063dSJacob Faibussowitsch   PetscCall(VecGetDM(r, &dm));
6759566063dSJacob Faibussowitsch   if (!dm) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf));
6762db13446SMatthew G. Knepley   else {
6772db13446SMatthew G. Knepley     PetscSection s, gs;
6782db13446SMatthew G. Knepley     PetscInt     Nf, f;
6792db13446SMatthew G. Knepley 
6809566063dSJacob Faibussowitsch     PetscCall(DMGetLocalSection(dm, &s));
6819566063dSJacob Faibussowitsch     PetscCall(DMGetGlobalSection(dm, &gs));
6829566063dSJacob Faibussowitsch     if (!s || !gs) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf));
6839566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetNumFields(s, &Nf));
68463a3b9bcSJacob Faibussowitsch     PetscCheck(Nf <= 256, PetscObjectComm((PetscObject)snes), PETSC_ERR_SUP, "Do not support %" PetscInt_FMT " fields > 256", Nf);
6859566063dSJacob Faibussowitsch     PetscCall(PetscSectionVecNorm(s, gs, r, NORM_2, res));
6869566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetTabLevel((PetscObject)snes, &tablevel));
6879566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, vf->format));
6889566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
68963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e [", its, (double)fgnorm));
6902db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
6919566063dSJacob Faibussowitsch       if (f) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
69263a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%14.12e", (double)res[f]));
6932db13446SMatthew G. Knepley     }
6949566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "] \n"));
6959566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
6969566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
6972db13446SMatthew G. Knepley   }
6983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6992db13446SMatthew G. Knepley }
700f6dfbefdSBarry Smith 
7014b828684SBarry Smith /*@C
702420bcc1bSBarry Smith   SNESConvergedDefault - Default convergence test for `SNESSolve()`.
703e7e93795SLois Curfman McInnes 
704c3339decSBarry Smith   Collective
705c7afd0dbSLois Curfman McInnes 
706e7e93795SLois Curfman McInnes   Input Parameters:
707f6dfbefdSBarry Smith + snes  - the `SNES` context
70806ee9f85SBarry Smith . it    - the iteration (0 indicates before any Newton steps)
709e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate
710c60f73f4SPeter Brune . snorm - 2-norm of current step
7117f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate
712*2a8381b2SBarry Smith - ctx   - unused context
713e7e93795SLois Curfman McInnes 
714184914b5SBarry Smith   Output Parameter:
7151ec80557SRené Chenard . reason - converged reason, see `SNESConvergedReason`
716c34cbdceSBarry Smith 
717c34cbdceSBarry Smith   Options Database Keys:
718f6dfbefdSBarry Smith + -snes_convergence_test default      - see `SNESSetFromOptions()`
719f362779dSJed Brown . -snes_stol                          - convergence tolerance in terms of the norm of the change in the solution between steps
720c34cbdceSBarry Smith . -snes_atol <abstol>                 - absolute tolerance of residual norm
721c34cbdceSBarry Smith . -snes_rtol <rtol>                   - relative decrease in tolerance norm from the initial 2-norm of the solution
722c34cbdceSBarry Smith . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
72377e5a1f9SBarry Smith . -snes_max_funcs <max_funcs>         - maximum number of function evaluations, use `unlimited` for no maximum
724c34cbdceSBarry Smith . -snes_max_fail <max_fail>           - maximum number of line search failures allowed before stopping, default is none
725f6dfbefdSBarry Smith - -snes_max_linear_solve_fail         - number of linear solver failures before `SNESSolve()` stops
726fee21e36SBarry Smith 
7270b4db180SJacob Faibussowitsch   Level: developer
72836851e7fSLois Curfman McInnes 
729420bcc1bSBarry Smith   Notes:
730420bcc1bSBarry Smith   This routine is not generally called directly. It is set with `SNESSetConvergenceTest()` automatically before the `SNESSolve()`.
731420bcc1bSBarry Smith 
732420bcc1bSBarry Smith   It can be called within a custom convergence test that should also apply the standard convergence tests
733420bcc1bSBarry Smith 
7341cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESConvergedSkip()`, `SNESSetTolerances()`, `SNESSetDivergenceTolerance()`,
7352fe279fdSBarry Smith           `SNESConvergedReason`
736e7e93795SLois Curfman McInnes @*/
SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason * reason,PetscCtx ctx)737*2a8381b2SBarry Smith PetscErrorCode SNESConvergedDefault(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, PetscCtx ctx)
738d71ae5a4SJacob Faibussowitsch {
7393a40ed3dSBarry Smith   PetscFunctionBegin;
7400700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
7414f572ea9SToby Isaac   PetscAssertPointer(reason, 6);
7423f149594SLisandro Dalcin 
74306ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
74406ee9f85SBarry Smith   if (!it) {
74506ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
74606ee9f85SBarry Smith     snes->ttol   = fnorm * snes->rtol;
747e37c518bSBarry Smith     snes->rnorm0 = fnorm;
74806ee9f85SBarry Smith   }
7498146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
7509566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n"));
75176c63389SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_NANORINF;
752be5caee7SBarry Smith   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
7539566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e\n", (double)fnorm, (double)snes->abstol));
754184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
755e71169deSBarry Smith   } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) {
75663a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", snes->nfuncs, snes->max_funcs));
757184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
75806ee9f85SBarry Smith   }
75906ee9f85SBarry Smith 
76006ee9f85SBarry Smith   if (it && !*reason) {
76106ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
7629566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e (relative tolerance)\n", (double)fnorm, (double)snes->ttol));
76306ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
764c60f73f4SPeter Brune     } else if (snorm < snes->stol * xnorm) {
7659566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes, "Converged due to small update length: %14.12e < %14.12e * %14.12e\n", (double)snorm, (double)snes->stol, (double)xnorm));
766c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
76777e5a1f9SBarry Smith     } else if (snes->divtol != PETSC_UNLIMITED && (fnorm > snes->divtol * snes->rnorm0)) {
7689566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes, "Diverged due to increase in function norm: %14.12e > %14.12e * %14.12e\n", (double)fnorm, (double)snes->divtol, (double)snes->rnorm0));
769e37c518bSBarry Smith       *reason = SNES_DIVERGED_DTOL;
77006ee9f85SBarry Smith     }
771e7e93795SLois Curfman McInnes   }
7723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
773e7e93795SLois Curfman McInnes }
7743f149594SLisandro Dalcin 
7753f149594SLisandro Dalcin /*@C
776f6dfbefdSBarry Smith   SNESConvergedSkip - Convergence test for `SNES` that NEVER returns as
7773f149594SLisandro Dalcin   converged, UNLESS the maximum number of iteration have been reached.
7783f149594SLisandro Dalcin 
779c3339decSBarry Smith   Logically Collective
7803f149594SLisandro Dalcin 
7813f149594SLisandro Dalcin   Input Parameters:
782f6dfbefdSBarry Smith + snes  - the `SNES` context
7833f149594SLisandro Dalcin . it    - the iteration (0 indicates before any Newton steps)
7843f149594SLisandro Dalcin . xnorm - 2-norm of current iterate
785c60f73f4SPeter Brune . snorm - 2-norm of current step
7863f149594SLisandro Dalcin . fnorm - 2-norm of function at current iterate
787*2a8381b2SBarry Smith - ctx   - unused context
7883f149594SLisandro Dalcin 
7893f149594SLisandro Dalcin   Output Parameter:
79076c63389SBarry Smith . reason - `SNES_CONVERGED_ITERATING`, `SNES_CONVERGED_ITS`, or `SNES_DIVERGED_FUNCTION_NANORINF`
7913f149594SLisandro Dalcin 
792f6dfbefdSBarry Smith   Options Database Key:
793f6dfbefdSBarry Smith . -snes_convergence_test skip - see `SNESSetFromOptions()`
794f362779dSJed Brown 
7953f149594SLisandro Dalcin   Level: advanced
7963f149594SLisandro Dalcin 
7970b4b7b1cSBarry Smith   Note:
7980b4b7b1cSBarry Smith   This is often used if `snes` is being used as a nonlinear smoother in `SNESFAS` or possibly other `SNESType`
7990b4b7b1cSBarry Smith 
8001cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESConvergedDefault()`, `SNESSetConvergenceTest()`, `SNESConvergedReason`
8013f149594SLisandro Dalcin @*/
SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason * reason,PetscCtx ctx)802*2a8381b2SBarry Smith PetscErrorCode SNESConvergedSkip(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, PetscCtx ctx)
803d71ae5a4SJacob Faibussowitsch {
8043f149594SLisandro Dalcin   PetscFunctionBegin;
8050700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
8064f572ea9SToby Isaac   PetscAssertPointer(reason, 6);
8073f149594SLisandro Dalcin 
8083f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
8093f149594SLisandro Dalcin 
8103f149594SLisandro Dalcin   if (fnorm != fnorm) {
8119566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n"));
81276c63389SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_NANORINF;
8133f149594SLisandro Dalcin   } else if (it == snes->max_its) {
8143f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
8153f149594SLisandro Dalcin   }
8163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8173f149594SLisandro Dalcin }
8183f149594SLisandro Dalcin 
819cc4c1da9SBarry Smith /*@
8200b4b7b1cSBarry Smith   SNESSetWorkVecs - Allocates a number of work vectors to be used internally by the `SNES` solver
82158c9b817SLisandro Dalcin 
82258c9b817SLisandro Dalcin   Input Parameters:
823f6dfbefdSBarry Smith + snes - the `SNES` context
824a2b725a8SWilliam Gropp - nw   - number of work vectors to allocate
82558c9b817SLisandro Dalcin 
82658c9b817SLisandro Dalcin   Level: developer
827fa0ddf94SBarry Smith 
828420bcc1bSBarry Smith   Note:
829420bcc1bSBarry Smith   Each `SNESType` calls this with the number of work vectors that particular type needs.
830420bcc1bSBarry Smith 
8311cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`
83298acb6afSMatthew G Knepley @*/
SNESSetWorkVecs(SNES snes,PetscInt nw)833d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetWorkVecs(SNES snes, PetscInt nw)
834d71ae5a4SJacob Faibussowitsch {
835c5ed8070SMatthew G. Knepley   DM  dm;
836c5ed8070SMatthew G. Knepley   Vec v;
83758c9b817SLisandro Dalcin 
83858c9b817SLisandro Dalcin   PetscFunctionBegin;
8399566063dSJacob Faibussowitsch   if (snes->work) PetscCall(VecDestroyVecs(snes->nwork, &snes->work));
84058c9b817SLisandro Dalcin   snes->nwork = nw;
841f5af7f23SKarl Rupp 
8429566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
8439566063dSJacob Faibussowitsch   PetscCall(DMGetGlobalVector(dm, &v));
8449566063dSJacob Faibussowitsch   PetscCall(VecDuplicateVecs(v, snes->nwork, &snes->work));
8459566063dSJacob Faibussowitsch   PetscCall(DMRestoreGlobalVector(dm, &v));
8463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
84758c9b817SLisandro Dalcin }
848