1
#ifdef PETSC_RCS_HEADER
2
static char vcid[] = "$Id: gsles.c,v 1.5 2000/01/10 03:54:18 knepley Exp $";
5
#include "petscsles.h" /*I "petscsles.h" I*/
6
#include "gsolver.h" /*I "gsolver.h" I*/
9
#define __FUNCT__ "GVecSolutionKSPMonitor"
11
GVecSolutionKSPMonitor - Monitors solution at each KSP iteration.
16
. ksp - The Krylov subspace context
17
. it - The number of iterations so far
18
. rnorm - The current (approximate) residual norm
23
.keywords: grid vector, ksp, monitor, solution
24
.seealso: KSPDefaultMonitor(),KSPSetMonitor(),GVecResidualKSPMonitor(),
25
GVecRhsKSPMonitor(), GVecErrorKSPMonitor()
27
int GVecSolutionKSPMonitor(KSP ksp, int it, PetscReal rnorm, void *ctx)
29
PetscViewer viewer = (PetscViewer) ctx;
34
PetscValidHeaderSpecific(ksp, KSP_COOKIE);
35
PetscValidHeaderSpecific(viewer, PETSC_VIEWER_COOKIE);
36
ierr = KSPBuildSolution(ksp, PETSC_NULL, &x); CHKERRQ(ierr);
37
ierr = VecView(x, viewer); CHKERRQ(ierr);
38
PetscFunctionReturn(0);
42
#define __FUNCT__ "GVecResidualKSPMonitor"
44
GVecResidualKSPMonitor - Monitors residual at each KSP iteration.
49
. ksp - The Krylov subspace context
50
. it - The number of iterations so far
51
. rnorm - The current (approximate) residual norm
56
.keywords: grid vector, ksp, monitor, residual
57
.seealso: KSPDefaultMonitor(),KSPSetMonitor(),GVecSolutionKSPMonitor(),
58
GVecRhsKSPMonitor(), GVecErrorKSPMonitor()
60
int GVecResidualKSPMonitor(KSP ksp, int it, PetscReal rnorm, void *ctx)
62
PetscViewer viewer = (PetscViewer) ctx;
67
PetscValidHeaderSpecific(ksp, KSP_COOKIE);
68
PetscValidHeaderSpecific(viewer, PETSC_VIEWER_COOKIE);
69
ierr = KSPBuildResidual(ksp, PETSC_NULL, PETSC_NULL, &r); CHKERRQ(ierr);
70
ierr = VecView(r, viewer); CHKERRQ(ierr);
71
PetscFunctionReturn(0);
75
#define __FUNCT__ "GVecRhsKSPMonitor"
77
GVecRhsKSPMonitor - Displays the right hand side for the linear system at the first iteration.
82
. ksp - The Krylov subspace context
83
. it - The number of iterations so far
84
. rnorm - The current (approximate) residual norm
89
.keywords: grid vector, ksp, monitor, rhs
90
.seealso: KSPDefaultMonitor(),KSPSetMonitor(),GVecSolutionKSPMonitor(),
91
GVecResidualKSPMonitor(), GVecErrorKSPMonitor()
93
int GVecRhsKSPMonitor(KSP ksp, int it, PetscReal rnorm, void *ctx)
95
PetscViewer viewer = (PetscViewer) ctx;
100
PetscValidHeaderSpecific(ksp, KSP_COOKIE);
101
PetscValidHeaderSpecific(viewer, PETSC_VIEWER_COOKIE);
103
ierr = KSPGetRhs(ksp, &b); CHKERRQ(ierr);
104
ierr = VecView(b, viewer); CHKERRQ(ierr);
106
PetscFunctionReturn(0);
110
#define __FUNCT__ "GVecErrorKSPMonitor"
112
GVecErrorKSPMonitor - Displays the error at each iteration.
117
. ksp - The Krylov subspace context
118
. it - The number of iterations so far
119
. rnorm - The current (approximate) residual norm
120
. errorCtx - A GVecErrorKSPMonitorCtx
123
The final argument to KSPSetMonitor() with this routine must be
124
a pointer to a GVecErrorKSPMonitorCtx.
128
.keywords: grid vector, ksp, monitor, error
129
.seealso: KSPDefaultMonitor(),KSPSetMonitor(),,GVecSolutionKSPMonitor(),
130
GVecResidualKSPMonitor(), GVecRhsKSPMonitor()
132
int GVecErrorKSPMonitor(KSP ksp, int it, PetscReal rnorm, void *errorCtx)
134
GVecErrorKSPMonitorCtx *ctx = (GVecErrorKSPMonitorCtx *) errorCtx;
135
PetscScalar mone = -1.0;
137
PetscReal norm_2, norm_max;
141
PetscValidHeaderSpecific(ksp, KSP_COOKIE);
142
ierr = KSPBuildSolution(ksp, PETSC_NULL, &x); CHKERRQ(ierr);
143
ierr = GVecGetWorkGVec(ctx->solution, &e); CHKERRQ(ierr);
144
ierr = VecWAXPY(&mone, x, ctx->solution, e); CHKERRQ(ierr);
145
ierr = VecView(e, ctx->error_viewer); CHKERRQ(ierr);
147
/* Compute 2-norm and max-norm of error */
148
if (ctx->norm_error_viewer) {
149
ierr = VecNorm(e, NORM_2, &norm_2); CHKERRQ(ierr);
150
ierr = VecNorm(e, NORM_MAX, &norm_max); CHKERRQ(ierr);
151
if (ctx->isInner == PETSC_FALSE) {
152
PetscViewerASCIIPrintf(ctx->norm_error_viewer, "Iteration %d residual norm %g error 2-norm %g error max-norm %g\n",
153
it, rnorm, norm_2, norm_max);
155
PetscViewerASCIIPrintf(ctx->norm_error_viewer, " Inner iteration %d residual norm %g error 2-norm %g error max-norm %g\n",
156
it, rnorm, norm_2, norm_max);
160
ierr = GVecRestoreWorkGVec(ctx->solution, &e); CHKERRQ(ierr);
161
PetscFunctionReturn(0);
166
#define __FUNCT__ "GVecPCMGSetMonitor"
167
/* ------------------------------------------------------------------------------*/
169
GVecPCMGSetMonitor - Sets GVec KSP monitors for each level of multigrid.
172
. pc - preconditioner context for multigrid
174
int GVecPCMGSetMonitor(PC pc, int views)
177
int levels, i,ierr, solution,rhs,residual,all;
180
PetscViewer *viewers;
184
PetscValidHeaderSpecific(pc, PC_COOKIE);
185
ierr = PetscTypeCompare((PetscObject) pc, PCMG, &match); CHKERRQ(ierr);
186
if (match == PETSC_FALSE) PetscFunctionReturn(0);
188
solution = (views & GVECPCMGMONITOR_SOLUTION);
189
residual = (views & GVECPCMGMONITOR_RESIDUAL);
190
rhs = (views & GVECPCMGMONITOR_RHS);
191
all = (solution != 0) + (residual != 0) + (rhs != 0);
193
ierr = MGGetLevels(pc, &levels); CHKERRQ(ierr);
195
ierr = PetscMalloc(all*levels * sizeof(PetscViewer), &viewers); CHKERRQ(ierr);
197
for(i = 0; i < levels; i++) {
198
ierr = MGGetSmoother(pc, i, &subsles); CHKERRQ(ierr);
199
ierr = SLESGetKSP(subsles, &ksp); CHKERRQ(ierr);
201
sprintf(name, "Right hand side %d",i);
202
ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD, 0, name, PETSC_DECIDE, PETSC_DECIDE, 200, 200, viewers); CHKERRQ(ierr);
203
ierr = KSPSetMonitor(ksp, GVecRhsKSPMonitor, *viewers++, PETSC_NULL); CHKERRQ(ierr);
206
sprintf(name, "Solution %d",i);
207
ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD, 0, name, PETSC_DECIDE, PETSC_DECIDE, 200, 200, viewers); CHKERRQ(ierr);
208
ierr = KSPSetMonitor(ksp, GVecSolutionKSPMonitor, *viewers++, PETSC_NULL); CHKERRQ(ierr);
211
sprintf(name, "Residual %d",i);
212
ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD, 0, name, PETSC_DECIDE, PETSC_DECIDE, 200, 200, viewers); CHKERRQ(ierr);
213
ierr = KSPSetMonitor(ksp, GVecResidualKSPMonitor, *viewers++, PETSC_NULL); CHKERRQ(ierr);
217
PetscFunctionReturn(0);
222
#define __FUNCT__ "GVecKSPOptionsChecker_Private"
223
int GVecKSPOptionsChecker_Private(KSP ksp)
225
char *prefix, string[64], *p;
226
int ierr, loc[4], nmax;
234
PetscValidHeaderSpecific(ksp, KSP_COOKIE);
235
ierr = KSPGetOptionsPrefix(ksp, &prefix); CHKERRQ(ierr);
236
ierr = PetscObjectGetComm((PetscObject) ksp, &comm); CHKERRQ(ierr);
239
loc[0] = PETSC_DECIDE; loc[1] = PETSC_DECIDE; loc[2] = 300; loc[3] = 300;
240
ierr = PetscOptionsGetIntArray(prefix, "-gvec_ksp_solutionmonitor", loc, &nmax, &opt); CHKERRQ(ierr);
242
ierr = PetscViewerDrawOpen(comm, 0, 0, loc[0], loc[1], loc[2], loc[3], &viewer); CHKERRQ(ierr);
243
ierr = PetscViewerDrawGetDraw(viewer, 0, &draw); CHKERRQ(ierr);
244
ierr = PetscDrawSetTitle(draw, "Approx. Solution"); CHKERRQ(ierr);
245
PetscLogObjectParent(ksp, (PetscObject) viewer);
246
ierr = KSPSetMonitor(ksp, GVecSolutionKSPMonitor, (void *) viewer, PETSC_NULL); CHKERRQ(ierr);
249
loc[0] = PETSC_DECIDE; loc[1] = PETSC_DECIDE; loc[2] = 300; loc[3] = 300;
250
ierr = PetscOptionsGetIntArray(prefix, "-gvec_ksp_residualmonitor", loc, &nmax, &opt); CHKERRQ(ierr);
252
ierr = PetscViewerDrawOpen(comm, 0, 0, loc[0], loc[1], loc[2], loc[3], &viewer); CHKERRQ(ierr);
253
ierr = PetscViewerDrawGetDraw(viewer, 0, &draw); CHKERRQ(ierr);
254
ierr = PetscDrawSetTitle(draw, "Residual"); CHKERRQ(ierr);
255
PetscLogObjectParent(ksp, (PetscObject) viewer);
256
ierr = KSPSetMonitor(ksp, GVecResidualKSPMonitor, (void *) viewer, PETSC_NULL); CHKERRQ(ierr);
259
loc[0] = PETSC_DECIDE; loc[1] = PETSC_DECIDE; loc[2] = 300; loc[3] = 300;
260
ierr = PetscOptionsGetIntArray(prefix, "-gvec_ksp_rhsmonitor", loc, &nmax, &opt); CHKERRQ(ierr);
262
ierr = PetscViewerDrawOpen(comm, 0, 0, loc[0], loc[1], loc[2], loc[3], &viewer); CHKERRQ(ierr);
263
ierr = PetscViewerDrawGetDraw(viewer, 0, &draw); CHKERRQ(ierr);
264
ierr = PetscDrawSetTitle(draw, "Rhs"); CHKERRQ(ierr);
265
PetscLogObjectParent(ksp, (PetscObject) viewer);
266
ierr = KSPSetMonitor(ksp, GVecRhsKSPMonitor, (void *) viewer, PETSC_NULL); CHKERRQ(ierr);
268
ierr = PetscOptionsGetString(prefix, "-gvec_mg_monitor", string, 64, &opt); CHKERRQ(ierr);
273
ierr = PetscStrstr(string, "nosolution", &p); CHKERRQ(ierr);
274
if (!p) all |= GVECPCMGMONITOR_SOLUTION;
275
ierr = PetscStrstr(string, "noresidual", &p); CHKERRQ(ierr);
276
if (!p) all |= GVECPCMGMONITOR_RESIDUAL;
277
ierr = PetscStrstr(string, "norhs", &p); CHKERRQ(ierr);
278
if (!p) all |= GVECPCMGMONITOR_RHS;
279
ierr = KSPGetPC(ksp, &pc); CHKERRQ(ierr);
280
ierr = GVecPCMGSetMonitor(pc, all); CHKERRQ(ierr);
282
ierr = PetscOptionsHasName(PETSC_NULL, "-help", &opt); CHKERRQ(ierr);
287
if (prefix != PETSC_NULL) {
288
ierr = PetscStrlen(prefix, &len); CHKERRQ(ierr);
290
ierr = PetscMalloc((len+2) * sizeof(char), &pprefix); CHKERRQ(ierr);
291
PetscStrcpy(pprefix, "-");
292
if (prefix != PETSC_NULL)
293
PetscStrcat(pprefix, prefix);
294
PetscPrintf(comm," Additional KSP Monitor options for grid vectors\n");
295
PetscPrintf(comm," %sgvec_ksp_solutionmonitor\n", pprefix);
296
PetscPrintf(comm," %sgvec_ksp_residualmonitor\n", pprefix);
297
PetscPrintf(comm," %sgvec_ksp_rhsmonitor\n", pprefix);
298
PetscPrintf(comm," %sgvec_mg_monitor [nosolution,norhs,noresidual]\n", pprefix);
299
ierr = PetscFree(pprefix); CHKERRQ(ierr);
301
PetscFunctionReturn(0);
305
/*--------------------------------------------------- Uzawa Methods --------------------------------------------------*/
307
#define __FUNCT__ "GMatCreateUzawa"
309
GMatCreateUzawa - Creates a container matrix for the Uzawa system matrix B^T A^{-1} B.
312
+ A - The square (0,0) block of the original saddle-point matrix
313
. B - The rectangular (0,1) block of the original saddle-point matrix
314
- sles - The solver used to invert A
317
. gmat - The discrete operator
321
.seealso: GVecCreate()
323
int GMatCreateUzawa(GMat A, GMat B, SLES sles, GMat *gmat)
333
PetscValidHeaderSpecific(A, MAT_COOKIE);
334
PetscValidHeaderSpecific(B, MAT_COOKIE);
335
PetscValidHeaderSpecific(sles, SLES_COOKIE);
336
PetscValidPointer(gmat);
337
ierr = GMatGetGrid(A, &grid); CHKERRQ(ierr);
338
ierr = GMatGetGrid(B, &grid2); CHKERRQ(ierr);
339
PetscValidHeaderSpecific(grid, GRID_COOKIE);
340
PetscValidHeaderSpecific(grid2, GRID_COOKIE);
341
if (grid != grid2) SETERRQ(PETSC_ERR_ARG_INCOMP, "Matrices must all have the same underlying grid.");
342
ierr = PetscNew(UzawaContext, &uCtx); CHKERRQ(ierr);
346
ierr = MatGetSize(A, &M, &N); CHKERRQ(ierr);
347
ierr = MatGetLocalSize(A, &m, &n); CHKERRQ(ierr);
348
ierr = MatGetSize(B, &O, &P); CHKERRQ(ierr);
349
ierr = MatGetLocalSize(B, &o, &p); CHKERRQ(ierr);
350
if ((m != o) || (n != o) || (M != O) || (N != O)) {
351
SETERRQ(PETSC_ERR_ARG_INCOMP, "Incommensurate sizes, B^T A B must be a legal matrix");
353
ierr = PetscObjectGetComm((PetscObject) grid, &comm); CHKERRQ(ierr);
354
ierr = MatCreateShell(comm, p, p, P, P, uCtx, gmat); CHKERRQ(ierr);
355
ierr = MatShellSetOperation(*gmat, MATOP_MULT, (void (*)(void)) GMatMatMultUzawa); CHKERRQ(ierr);
356
ierr = VecCreateMPI(comm, m, M, &uCtx->work); CHKERRQ(ierr);
357
ierr = VecDuplicate(uCtx->work, &uCtx->work2); CHKERRQ(ierr);
358
PetscFunctionReturn(0);
362
#define __FUNCT__ "GMatMatMultUzawa"
364
GMatMatMultUzawa - This function applies B^T A^{-1} B to a vector,
365
which is the Schur complement matrix.
368
+ mat - The grid matrix
369
- x - The input grid vector
372
. y - The output grid vector B^T A^{-1} B x
376
.seealso: GMatEvaluateOperatorGalerkin
378
int GMatMatMultUzawa(GMat mat, GVec x, GVec y)
385
PetscValidHeaderSpecific(mat, MAT_COOKIE);
386
PetscValidHeaderSpecific(x, VEC_COOKIE);
387
PetscValidHeaderSpecific(y, VEC_COOKIE);
388
ierr = MatShellGetContext(mat, (void **) &ctx); CHKERRQ(ierr);
389
ierr = MatMult(ctx->B, x, ctx->work); CHKERRQ(ierr);
390
ierr = SLESSolve(ctx->sles, ctx->work, ctx->work2, &its); CHKERRQ(ierr);
391
ierr = MatMultTranspose(ctx->B, ctx->work2, y); CHKERRQ(ierr);
392
PetscFunctionReturn(0);
396
#define __FUNCT__ "GMatDestroyUzawa"
398
GMatDestroyUzawa - Destroys a container matrix for the Uzawa
399
system matrix B^T A B.
402
. gmat - The container matrix from GMatCreateUzawa()
406
.seealso: GVecCreate()
408
int GMatDestroyUzawa(GMat gmat)
414
PetscValidHeaderSpecific(gmat, MAT_COOKIE);
416
ierr = MatShellGetContext(gmat, (void **) &ctx); CHKERRQ(ierr);
417
if (ctx != PETSC_NULL) {
418
ierr = VecDestroy(ctx->work); CHKERRQ(ierr);
419
ierr = VecDestroy(ctx->work2); CHKERRQ(ierr);
420
ierr = PetscFree(ctx); CHKERRQ(ierr);
422
ierr = MatDestroy(gmat); CHKERRQ(ierr);
423
PetscFunctionReturn(0);