/* Monitor - User-provided routine to monitor the solution computed at each timestep. This example plots the solution and computes the error in two different norms. Input Parameters: ts - the timestep context step - the count of the current step (with 0 meaning the initial condition) time - the current time u - the solution at this timestep ctx - the user-provided context for this monitoring routine. In this case we use the application context which contains information about the problem size, workspace and the exact solution. */ PetscErrorCode Monitor(TS ts,PetscInt step,PetscReal time,Vec u,void *ctx) { AppCtx *appctx = (AppCtx*) ctx; /* user-defined application context */ PetscErrorCode ierr; PetscReal en2,en2s,enmax; PetscDraw draw; /* We use the default X windows viewer PETSC_VIEWER_DRAW_(appctx->comm) that is associated with the current communicator. This saves the effort of calling PetscViewerDrawOpen() to create the window. Note that if we wished to plot several items in separate windows we would create each viewer with PetscViewerDrawOpen() and store them in the application context, appctx. PetscReal buffering makes graphics look better. */ ierr = PetscViewerDrawGetDraw(PETSC_VIEWER_DRAW_(appctx->comm),0,&draw);CHKERRQ(ierr); ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr); ierr = VecView(u,PETSC_VIEWER_DRAW_(appctx->comm));CHKERRQ(ierr); /* Compute the exact solution at this timestep */ ierr = ExactSolution(time,appctx->solution,appctx);CHKERRQ(ierr); /* Print debugging information if desired */ if (appctx->debug) { ierr = PetscPrintf(appctx->comm,"Computed solution vector\n");CHKERRQ(ierr); ierr = VecView(u,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(appctx->comm,"Exact solution vector\n");CHKERRQ(ierr); ierr = VecView(appctx->solution,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Compute the 2-norm and max-norm of the error */ ierr = VecAXPY(appctx->solution,-1.0,u);CHKERRQ(ierr); ierr = VecNorm(appctx->solution,NORM_2,&en2);CHKERRQ(ierr); en2s = PetscSqrtReal(appctx->h)*en2; /* scale the 2-norm by the grid spacing */ ierr = VecNorm(appctx->solution,NORM_MAX,&enmax);CHKERRQ(ierr); /* PetscPrintf() causes only the first processor in this communicator to print the timestep information. */ ierr = PetscPrintf(appctx->comm,"Timestep %D: time = %g,2-norm error = %g, max norm error = %g\n",step,(double)time,(double)en2s,(double)enmax);CHKERRQ(ierr); /* Print debugging information if desired */ /* if (appctx->debug) { ierr = PetscPrintf(appctx->comm,"Error vector\n");CHKERRQ(ierr); ierr = VecView(appctx->solution,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } */ return 0; }
/*@C DMMGSolve - Actually solves the (non)linear system defined with the DMMG Collective on DMMG Input Parameter: . dmmg - the context Level: advanced Options Database: + -dmmg_grid_sequence - use grid sequencing to get the initial solution for each level from the previous - -dmmg_monitor_solution - display the solution at each iteration Notes: For linear (KSP) problems may be called more than once, uses the same matrices but recomputes the right hand side for each new solve. Call DMMGSetKSP() to generate new matrices. .seealso DMMGCreate(), DMMGDestroy(), DMMG, DMMGSetSNES(), DMMGSetKSP(), DMMGSetUp(), DMMGSetMatType() @*/ PetscErrorCode PETSCSNES_DLLEXPORT DMMGSolve(DMMG *dmmg) { PetscErrorCode ierr; PetscInt i,nlevels = dmmg[0]->nlevels; PetscTruth gridseq = PETSC_FALSE,vecmonitor = PETSC_FALSE,flg; PetscFunctionBegin; ierr = PetscOptionsGetTruth(0,"-dmmg_grid_sequence",&gridseq,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetTruth(0,"-dmmg_monitor_solution",&vecmonitor,PETSC_NULL);CHKERRQ(ierr); if (gridseq) { if (dmmg[0]->initialguess) { ierr = (*dmmg[0]->initialguess)(dmmg[0],dmmg[0]->x);CHKERRQ(ierr); if (dmmg[0]->ksp && !dmmg[0]->snes) { ierr = KSPSetInitialGuessNonzero(dmmg[0]->ksp,PETSC_TRUE);CHKERRQ(ierr); } } for (i=0; i<nlevels-1; i++) { ierr = (*dmmg[i]->solve)(dmmg,i);CHKERRQ(ierr); if (vecmonitor) { ierr = VecView(dmmg[i]->x,PETSC_VIEWER_DRAW_(dmmg[i]->comm));CHKERRQ(ierr); } ierr = MatInterpolate(dmmg[i+1]->R,dmmg[i]->x,dmmg[i+1]->x);CHKERRQ(ierr); if (dmmg[i+1]->ksp && !dmmg[i+1]->snes) { ierr = KSPSetInitialGuessNonzero(dmmg[i+1]->ksp,PETSC_TRUE);CHKERRQ(ierr); } } } else { if (dmmg[nlevels-1]->initialguess) { ierr = (*dmmg[nlevels-1]->initialguess)(dmmg[nlevels-1],dmmg[nlevels-1]->x);CHKERRQ(ierr); } } /*ierr = VecView(dmmg[nlevels-1]->x,PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);*/ ierr = (*DMMGGetFine(dmmg)->solve)(dmmg,nlevels-1);CHKERRQ(ierr); if (vecmonitor) { ierr = VecView(dmmg[nlevels-1]->x,PETSC_VIEWER_DRAW_(dmmg[nlevels-1]->comm));CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsGetTruth(PETSC_NULL,"-dmmg_view",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg && !PetscPreLoadingOn) { PetscViewer viewer; ierr = PetscViewerASCIIGetStdout(dmmg[0]->comm,&viewer);CHKERRQ(ierr); ierr = DMMGView(dmmg,viewer);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsGetTruth(PETSC_NULL,"-dmmg_view_binary",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg && !PetscPreLoadingOn) { ierr = DMMGView(dmmg,PETSC_VIEWER_BINARY_(dmmg[0]->comm));CHKERRQ(ierr); } PetscFunctionReturn(0); }
Draw( unsigned dim_, const MPI_Comm comm ) : dim( dim_ ) { // static unsigned w{0}; window = _draw_window_num_; _draw_window_num_ += 1; viewer = PETSC_VIEWER_DRAW_( comm ); PetscViewerDrawGetDraw( viewer, static_cast<int>( window ), &draw ); PetscViewerDrawGetDrawLG( viewer, static_cast<int>( window ), &lg ); PetscDrawSetDoubleBuffer( draw ); PetscDrawLGSetDimension( lg, static_cast<int>( dim ) ); PetscDrawLGGetAxis( lg, &axis ); }
/*@C KSPMonitorSolution - Monitors progress of the KSP solvers by calling VecView() for the approximate solution at each iteration. Collective on KSP Input Parameters: + ksp - the KSP context . its - iteration number . fgnorm - 2-norm of residual (or gradient) - dummy - either a viewer or NULL Level: intermediate Notes: For some Krylov methods such as GMRES constructing the solution at each iteration is expensive, hence using this will slow the code. .keywords: KSP, nonlinear, vector, monitor, view .seealso: KSPMonitorSet(), KSPMonitorDefault(), VecView() @*/ PetscErrorCode KSPMonitorSolution(KSP ksp,PetscInt its,PetscReal fgnorm,void *dummy) { PetscErrorCode ierr; Vec x; PetscViewer viewer = (PetscViewer) dummy; PetscFunctionBegin; ierr = KSPBuildSolution(ksp,NULL,&x);CHKERRQ(ierr); if (!viewer) { MPI_Comm comm; ierr = PetscObjectGetComm((PetscObject)ksp,&comm);CHKERRQ(ierr); viewer = PETSC_VIEWER_DRAW_(comm); } ierr = VecView(x,viewer);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling VecView() for the UPDATE to the solution at each iteration. Collective on SNES Input Parameters: + snes - the SNES context . its - iteration number . fgnorm - 2-norm of residual - dummy - either a viewer or NULL Level: intermediate .keywords: SNES, nonlinear, vector, monitor, view .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() @*/ PetscErrorCode SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) { PetscErrorCode ierr; Vec x; PetscViewer viewer = (PetscViewer) dummy; PetscFunctionBegin; ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr); if (!viewer) { MPI_Comm comm; ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); viewer = PETSC_VIEWER_DRAW_(comm); } ierr = VecView(x,viewer);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscDrawLG lg; PetscErrorCode ierr; PetscInt Mx = 100,i; PetscReal x,hx = .1/Mx,pause,xx[3],yy[3]; PetscDraw draw; const char *const legend[] = {"(1 - u^2)^2","1 - u^2","-(1 - u)log(1 - u)"}; PetscDrawAxis axis; static PetscDrawViewPorts *ports = 0; PetscFunctionBegin; PetscInitialize(&argc,&argv,0,help); ierr = PetscViewerDrawResize(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),1200,800);CHKERRQ(ierr); ierr = PetscViewerDrawGetDrawLG(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),0,&lg);CHKERRQ(ierr); ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr); if (!ports) { ierr = PetscDrawViewPortsCreateRect(draw,1,2,&ports);CHKERRQ(ierr); } ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr); ierr = PetscDrawLGReset(lg);CHKERRQ(ierr); /* Plot the energies */ ierr = PetscDrawLGSetDimension(lg,3);CHKERRQ(ierr); ierr = PetscDrawViewPortsSet(ports,1);CHKERRQ(ierr); x = .9; for (i=0; i<Mx; i++) { xx[0] = xx[1] = xx[2] = x; yy[0] = (1.-x*x)*(1. - x*x); yy[1] = (1. - x*x); yy[2] = -(1.-x)*PetscLogScalar(1.-x); ierr = PetscDrawLGAddPoint(lg,xx,yy);CHKERRQ(ierr); x += hx; } ierr = PetscDrawGetPause(draw,&pause);CHKERRQ(ierr); ierr = PetscDrawSetPause(draw,0.0);CHKERRQ(ierr); ierr = PetscDrawAxisSetLabels(axis,"Energy","","");CHKERRQ(ierr); ierr = PetscDrawLGSetLegend(lg,legend);CHKERRQ(ierr); ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); /* Plot the forces */ ierr = PetscDrawViewPortsSet(ports,0);CHKERRQ(ierr); ierr = PetscDrawLGReset(lg);CHKERRQ(ierr); x = .9; for (i=0; i<Mx; i++) { xx[0] = xx[1] = xx[2] = x; yy[0] = x*x*x - x; yy[1] = -x; yy[2] = 1.0 + PetscLogScalar(1. - x); ierr = PetscDrawLGAddPoint(lg,xx,yy);CHKERRQ(ierr); x += hx; } ierr = PetscDrawAxisSetLabels(axis,"Derivative","","");CHKERRQ(ierr); ierr = PetscDrawLGSetLegend(lg,PETSC_NULL);CHKERRQ(ierr); ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); ierr = PetscDrawSetPause(draw,pause);CHKERRQ(ierr); ierr = PetscDrawPause(draw);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* This routine is not parallel */ PetscErrorCode MyMonitor(TS ts,PetscInt step,PetscReal time,Vec U,void *ptr) { UserCtx *ctx = (UserCtx*)ptr; PetscDrawLG lg; PetscErrorCode ierr; PetscScalar *u; PetscInt Mx,i,xs,xm,cnt; PetscReal x,y,hx,pause,sx,len,max,xx[2],yy[2]; PetscDraw draw; Vec localU; DM da; int colors[] = {PETSC_DRAW_YELLOW,PETSC_DRAW_RED,PETSC_DRAW_BLUE}; const char*const legend[] = {"-kappa (\\grad u,\\grad u)","(1 - u^2)^2"}; PetscDrawAxis axis; PetscDrawViewPorts *ports; PetscReal vbounds[] = {-1.1,1.1}; PetscFunctionBegin; ierr = PetscViewerDrawSetBounds(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),1,vbounds);CHKERRQ(ierr); ierr = PetscViewerDrawResize(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),1200,800);CHKERRQ(ierr); ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMGetLocalVector(da,&localU);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); hx = 1.0/(PetscReal)Mx; sx = 1.0/(hx*hx); ierr = DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(da,localU,&u);CHKERRQ(ierr); ierr = PetscViewerDrawGetDrawLG(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),1,&lg);CHKERRQ(ierr); ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr); if (!ctx->ports) { ierr = PetscDrawViewPortsCreateRect(draw,1,3,&ctx->ports);CHKERRQ(ierr); } ports = ctx->ports; ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr); ierr = PetscDrawLGReset(lg);CHKERRQ(ierr); xx[0] = 0.0; xx[1] = 1.0; cnt = 2; ierr = PetscOptionsGetRealArray(NULL,NULL,"-zoom",xx,&cnt,NULL);CHKERRQ(ierr); xs = xx[0]/hx; xm = (xx[1] - xx[0])/hx; /* Plot the energies */ ierr = PetscDrawLGSetDimension(lg,1 + (ctx->allencahn ? 1 : 0));CHKERRQ(ierr); ierr = PetscDrawLGSetColors(lg,colors+1);CHKERRQ(ierr); ierr = PetscDrawViewPortsSet(ports,2);CHKERRQ(ierr); x = hx*xs; for (i=xs; i<xs+xm; i++) { xx[0] = xx[1] = x; yy[0] = PetscRealPart(.25*ctx->kappa*(u[i-1] - u[i+1])*(u[i-1] - u[i+1])*sx); if (ctx->allencahn) yy[1] = .25*PetscRealPart((1. - u[i]*u[i])*(1. - u[i]*u[i])); ierr = PetscDrawLGAddPoint(lg,xx,yy);CHKERRQ(ierr); x += hx; } ierr = PetscDrawGetPause(draw,&pause);CHKERRQ(ierr); ierr = PetscDrawSetPause(draw,0.0);CHKERRQ(ierr); ierr = PetscDrawAxisSetLabels(axis,"Energy","","");CHKERRQ(ierr); ierr = PetscDrawLGSetLegend(lg,legend);CHKERRQ(ierr); ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); /* Plot the forces */ ierr = PetscDrawViewPortsSet(ports,1);CHKERRQ(ierr); ierr = PetscDrawLGReset(lg);CHKERRQ(ierr); x = xs*hx;; max = 0.; for (i=xs; i<xs+xm; i++) { xx[0] = xx[1] = x; yy[0] = PetscRealPart(ctx->kappa*(u[i-1] + u[i+1] - 2.0*u[i])*sx); max = PetscMax(max,PetscAbs(yy[0])); if (ctx->allencahn) { yy[1] = PetscRealPart(u[i] - u[i]*u[i]*u[i]); max = PetscMax(max,PetscAbs(yy[1])); } ierr = PetscDrawLGAddPoint(lg,xx,yy);CHKERRQ(ierr); x += hx; } ierr = PetscDrawAxisSetLabels(axis,"Right hand side","","");CHKERRQ(ierr); ierr = PetscDrawLGSetLegend(lg,NULL);CHKERRQ(ierr); ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); /* Plot the solution */ ierr = PetscDrawLGSetDimension(lg,1);CHKERRQ(ierr); ierr = PetscDrawViewPortsSet(ports,0);CHKERRQ(ierr); ierr = PetscDrawLGReset(lg);CHKERRQ(ierr); x = hx*xs; ierr = PetscDrawLGSetLimits(lg,x,x+(xm-1)*hx,-1.1,1.1);CHKERRQ(ierr); ierr = PetscDrawLGSetColors(lg,colors);CHKERRQ(ierr); for (i=xs; i<xs+xm; i++) { xx[0] = x; yy[0] = PetscRealPart(u[i]); ierr = PetscDrawLGAddPoint(lg,xx,yy);CHKERRQ(ierr); x += hx; } ierr = PetscDrawAxisSetLabels(axis,"Solution","","");CHKERRQ(ierr); ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); /* Print the forces as arrows on the solution */ x = hx*xs; cnt = xm/60; cnt = (!cnt) ? 1 : cnt; for (i=xs; i<xs+xm; i += cnt) { y = PetscRealPart(u[i]); len = .5*PetscRealPart(ctx->kappa*(u[i-1] + u[i+1] - 2.0*u[i])*sx)/max; ierr = PetscDrawArrow(draw,x,y,x,y+len,PETSC_DRAW_RED);CHKERRQ(ierr); if (ctx->allencahn) { len = .5*PetscRealPart(u[i] - u[i]*u[i]*u[i])/max; ierr = PetscDrawArrow(draw,x,y,x,y+len,PETSC_DRAW_BLUE);CHKERRQ(ierr); } x += cnt*hx; } ierr = DMDAVecRestoreArrayRead(da,localU,&x);CHKERRQ(ierr); ierr = DMRestoreLocalVector(da,&localU);CHKERRQ(ierr); ierr = PetscDrawStringSetSize(draw,.2,.2);CHKERRQ(ierr); ierr = PetscDrawFlush(draw);CHKERRQ(ierr); ierr = PetscDrawSetPause(draw,pause);CHKERRQ(ierr); ierr = PetscDrawPause(draw);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec x,r; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscInt steps,Mx,maxsteps = 10000000; PetscErrorCode ierr; DM da; MatFDColoring matfdcoloring; ISColoring iscoloring; PetscReal dt; PetscReal vbounds[] = {-100000,100000,-1.1,1.1}; PetscBool wait; Vec ul,uh; SNES snes; UserCtx ctx; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ctx.kappa = 1.0; ierr = PetscOptionsGetReal(NULL,"-kappa",&ctx.kappa,NULL);CHKERRQ(ierr); ctx.cahnhillard = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL,"-cahn-hillard",&ctx.cahnhillard,NULL);CHKERRQ(ierr); ierr = PetscViewerDrawSetBounds(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),2,vbounds);CHKERRQ(ierr); ierr = PetscViewerDrawResize(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),600,600);CHKERRQ(ierr); ctx.energy = 1; /* ierr = PetscOptionsGetInt(NULL,NULL,"-energy",&ctx.energy,NULL);CHKERRQ(ierr); */ ierr = PetscOptionsGetInt(NULL,NULL,"-energy",&ctx.energy,NULL);CHKERRQ(ierr); ctx.tol = 1.0e-8; ierr = PetscOptionsGetReal(NULL,"-tol",&ctx.tol,NULL);CHKERRQ(ierr); ctx.theta = .001; ctx.theta_c = 1.0; ierr = PetscOptionsGetReal(NULL,"-theta",&ctx.theta,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-theta_c",&ctx.theta_c,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, -10,2,2,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"Biharmonic heat equation: w = -kappa*u_xx");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"Biharmonic heat equation: u");CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&Mx,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); dt = 1.0/(10.*ctx.kappa*Mx*Mx*Mx*Mx); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; then duplicate for remaining vectors that are the same types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,FormFunction,&ctx);CHKERRQ(ierr); ierr = TSSetDuration(ts,maxsteps,.02);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create matrix data structure; set Jacobian evaluation routine < Set Jacobian matrix data structure and default Jacobian evaluation routine. User can override with: -snes_mf : matrix-free Newton-Krylov method with no preconditioning (unless user explicitly sets preconditioner) -snes_mf_operator : form preconditioning matrix as set by the user, but use matrix-free approx for Jacobian-vector products within Newton-Krylov method - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = DMCreateColoring(da,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(da,&J);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))SNESTSFormFunction,ts);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetUp(J,iscoloring,matfdcoloring);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefaultColor,matfdcoloring);CHKERRQ(ierr); { ierr = VecDuplicate(x,&ul);CHKERRQ(ierr); ierr = VecDuplicate(x,&uh);CHKERRQ(ierr); ierr = VecStrideSet(ul,0,PETSC_NINFINITY);CHKERRQ(ierr); ierr = VecStrideSet(ul,1,-1.0);CHKERRQ(ierr); ierr = VecStrideSet(uh,0,PETSC_INFINITY);CHKERRQ(ierr); ierr = VecStrideSet(uh,1,1.0);CHKERRQ(ierr); ierr = TSVISetVariableBounds(ts,ul,uh);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(da,x,ctx.kappa);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr); ierr = TSSetSolution(ts,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,x);CHKERRQ(ierr); wait = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL,"-wait",&wait,NULL);CHKERRQ(ierr); if (wait) { ierr = PetscSleep(-1);CHKERRQ(ierr); } ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { ierr = VecDestroy(&ul);CHKERRQ(ierr); ierr = VecDestroy(&uh);CHKERRQ(ierr); } ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
/*@C PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user Collective on MPI_Comm Input Parameters: + comm - the communicator to own the viewer . pre - the string to prepend to the name or NULL - name - the option one is seeking Output Parameter: + viewer - the viewer, pass NULL if not needed . format - the PetscViewerFormat requested by the user, pass NULL if not needed - set - PETSC_TRUE if found, else PETSC_FALSE Level: intermediate Notes: If no value is provided ascii:stdout is used $ ascii[:[filename][:[format][:append]]] defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab, for example ascii::ascii_info prints just the information about the object not all details unless :append is given filename opens in write mode, overwriting what was already there $ binary[:[filename][:[format][:append]]] defaults to the file binaryoutput $ draw[:drawtype] for example, draw:tikz or draw:x $ socket[:port] defaults to the standard output port $ saws[:communicatorname] publishes object to the Scientific Application Webserver (SAWs) Use PetscViewerDestroy() after using the viewer, otherwise a memory leak will occur .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), PetscOptionsFList(), PetscOptionsEList() @*/ PetscErrorCode PetscOptionsGetViewer(MPI_Comm comm,const char pre[],const char name[],PetscViewer *viewer,PetscViewerFormat *format,PetscBool *set) { char *value; PetscErrorCode ierr; PetscBool flag,hashelp; PetscFunctionBegin; PetscValidCharPointer(name,3); ierr = PetscOptionsHasName(NULL,"-help",&hashelp);CHKERRQ(ierr); if (hashelp) { ierr = (*PetscHelpPrintf)(comm," -%s%s ascii[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Triggers display of a PETSc object to screen or ASCII file","PetscOptionsGetViewer");CHKERRQ(ierr); ierr = (*PetscHelpPrintf)(comm," -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Triggers saving of a PETSc object to a binary file","PetscOptionsGetViewer");CHKERRQ(ierr); ierr = (*PetscHelpPrintf)(comm," -%s%s draw[:drawtype]: %s (%s)\n",pre ? pre : "",name+1,"Triggers drawing of a PETSc object","PetscOptionsGetViewer");CHKERRQ(ierr); ierr = (*PetscHelpPrintf)(comm," -%s%s socket[:port]: %s (%s)\n",pre ? pre : "",name+1,"Triggers push of a PETSc object to a Unix socket","PetscOptionsGetViewer");CHKERRQ(ierr); ierr = (*PetscHelpPrintf)(comm," -%s%s saws[:communicatorname]: %s (%s)\n",pre ? pre : "",name+1,"Triggers publishing of a PETSc object to SAWs","PetscOptionsGetViewer");CHKERRQ(ierr); } if (format) *format = PETSC_VIEWER_DEFAULT; if (set) *set = PETSC_FALSE; ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr); if (flag) { if (set) *set = PETSC_TRUE; if (!value) { if (viewer) { ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr); } } else { char *loc0_vtype,*loc1_fname,*loc2_fmt = NULL,*loc3_fmode = NULL; PetscInt cnt; const char *viewers[] = {PETSCVIEWERASCII,PETSCVIEWERBINARY,PETSCVIEWERDRAW,PETSCVIEWERSOCKET,PETSCVIEWERMATLAB,PETSCVIEWERSAWS,PETSCVIEWERVTK,PETSCVIEWERHDF5,0}; ierr = PetscStrallocpy(value,&loc0_vtype);CHKERRQ(ierr); ierr = PetscStrchr(loc0_vtype,':',&loc1_fname);CHKERRQ(ierr); if (loc1_fname) { *loc1_fname++ = 0; ierr = PetscStrchr(loc1_fname,':',&loc2_fmt);CHKERRQ(ierr); } if (loc2_fmt) { *loc2_fmt++ = 0; ierr = PetscStrchr(loc2_fmt,':',&loc3_fmode);CHKERRQ(ierr); } if (loc3_fmode) *loc3_fmode++ = 0; ierr = PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii",viewers,&cnt);CHKERRQ(ierr); if (cnt > (PetscInt) sizeof(viewers)-1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown viewer type: %s",loc0_vtype); if (viewer) { if (!loc1_fname) { switch (cnt) { case 0: ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr); break; case 1: if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) CHKERRQ(PETSC_ERR_PLIB); break; case 2: if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) CHKERRQ(PETSC_ERR_PLIB); break; #if defined(PETSC_USE_SOCKET_VIEWER) case 3: if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) CHKERRQ(PETSC_ERR_PLIB); break; #endif #if defined(PETSC_HAVE_MATLAB_ENGINE) case 4: if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) CHKERRQ(PETSC_ERR_PLIB); break; #endif #if defined(PETSC_HAVE_SAWS) case 5: if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) CHKERRQ(PETSC_ERR_PLIB); break; #endif #if defined(PETSC_HAVE_HDF5) case 7: if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) CHKERRQ(PETSC_ERR_PLIB); break; #endif default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported viewer %s",loc0_vtype); } ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr); } else { if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */ ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr); } else { PetscFileMode fmode; ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr); ierr = PetscViewerSetType(*viewer,*loc0_vtype ? loc0_vtype : "ascii");CHKERRQ(ierr); fmode = FILE_MODE_WRITE; if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */ ierr = PetscEnumFind(PetscFileModes,loc3_fmode,(PetscEnum*)&fmode,&flag);CHKERRQ(ierr); if (!flag) SETERRQ1(comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown file mode: %s",loc3_fmode); } ierr = PetscViewerFileSetMode(*viewer,flag?fmode:FILE_MODE_WRITE);CHKERRQ(ierr); ierr = PetscViewerFileSetName(*viewer,loc1_fname);CHKERRQ(ierr); ierr = PetscViewerDrawSetDrawType(*viewer,loc1_fname);CHKERRQ(ierr); } } } if (viewer) { ierr = PetscViewerSetUp(*viewer);CHKERRQ(ierr); } if (loc2_fmt && *loc2_fmt) { ierr = PetscEnumFind(PetscViewerFormats,loc2_fmt,(PetscEnum*)format,&flag);CHKERRQ(ierr); if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer format %s",loc2_fmt);CHKERRQ(ierr); } ierr = PetscFree(loc0_vtype);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
/*@ KSPSetFromOptions - Sets KSP options from the options database. This routine must be called before KSPSetUp() if the user is to be allowed to set the Krylov type. Collective on KSP Input Parameters: . ksp - the Krylov space context Options Database Keys: + -ksp_max_it - maximum number of linear iterations . -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e. if residual norm decreases by this factor than convergence is declared . -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual norm is less than this then convergence is declared . -ksp_divtol tol - if residual norm increases by this factor than divergence is declared . -ksp_converged_use_initial_residual_norm - see KSPConvergedDefaultSetUIRNorm() . -ksp_converged_use_min_initial_residual_norm - see KSPConvergedDefaultSetUMIRNorm() . -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using convergence test (say you always want to run with 5 iterations) to save on communication overhead preconditioned - default for left preconditioning unpreconditioned - see KSPSetNormType() natural - see KSPSetNormType() . -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration) works only for PCBCGS, PCIBCGS and and PCCG . -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations. This will require 1 more iteration of the solver than usual. . -ksp_guess_type - Type of initial guess generator for repeated linear solves . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves . -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space . -ksp_test_null_space - tests the null space set with MatSetNullSpace() to see if it truly is a null space . -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side . -ksp_monitor_cancel - cancel all previous convergene monitor routines set . -ksp_monitor <optional filename> - print residual norm at each iteration . -ksp_monitor_lg_residualnorm - plot residual norm at each iteration . -ksp_monitor_solution [ascii binary or draw][:filename][:format option] - plot solution at each iteration - -ksp_monitor_singular_value - monitor extreme singular values at each iteration Notes: To see all options, run your program with the -help option or consult Users-Manual: ch_ksp Level: beginner .keywords: KSP, set, from, options, database .seealso: KSPSetOptionsPrefix(), KSPResetFromOptions(), KSPSetUseFischerGuess() @*/ PetscErrorCode KSPSetFromOptions(KSP ksp) { PetscInt indx; const char *convtests[] = {"default","skip","lsqr"}; char type[256], guesstype[256], monfilename[PETSC_MAX_PATH_LEN]; PetscBool flg,flag,reuse,set; PetscInt model[2]={0,0},nmax; KSPNormType normtype; PCSide pcside; void *ctx; MPI_Comm comm; const char *prefix; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); ierr = PetscObjectGetComm((PetscObject) ksp, &comm);CHKERRQ(ierr); ierr = PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);CHKERRQ(ierr); if (!ksp->skippcsetfromoptions) { if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);} ierr = PCSetFromOptions(ksp->pc);CHKERRQ(ierr); } ierr = KSPRegisterAll();CHKERRQ(ierr); ierr = PetscObjectOptionsBegin((PetscObject)ksp);CHKERRQ(ierr); ierr = PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetType(ksp,type);CHKERRQ(ierr); } /* Set the type if it was never set. */ if (!((PetscObject)ksp)->type_name) { ierr = KSPSetType(ksp,KSPGMRES);CHKERRQ(ierr); } ierr = KSPResetViewers(ksp);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg);CHKERRQ(ierr); if (flg) { ierr = PCGetReusePreconditioner(ksp->pc,&reuse);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one ","KSPReusePreconditioner",reuse,&reuse,NULL);CHKERRQ(ierr); ierr = KSPSetReusePreconditioner(ksp,reuse);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view", &ksp->viewer, &ksp->format, &ksp->view);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_converged_reason", &ksp->viewerReason, &ksp->formatReason, &ksp->viewReason);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat", &ksp->viewerMat, &ksp->formatMat, &ksp->viewMat);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat", &ksp->viewerPMat, &ksp->formatPMat, &ksp->viewPMat);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs", &ksp->viewerRhs, &ksp->formatRhs, &ksp->viewRhs);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution", &ksp->viewerSol, &ksp->formatSol, &ksp->viewSol);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit", &ksp->viewerMatExp, &ksp->formatMatExp, &ksp->viewMatExp);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual", &ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp, &ksp->formatPOpExp, &ksp->viewPOpExp);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale", &ksp->viewerDScale, &ksp->formatDScale, &ksp->viewDScale);CHKERRQ(ierr); ierr = KSPGetDiagonalScale(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetDiagonalScale(ksp,flag);CHKERRQ(ierr); } ierr = KSPGetDiagonalScaleFix(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetDiagonalScaleFix(ksp,flag);CHKERRQ(ierr); } goto skipoptions; } ierr = PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",PETSC_FALSE,&flag,&set);CHKERRQ(ierr); if (set && flag) {ierr = KSPConvergedDefaultSetUIRNorm(ksp);CHKERRQ(ierr);} ierr = PetscOptionsBool("-ksp_converged_use_min_initial_residual_norm","Use minimum of initial residual norm and b for computing relative convergence","KSPConvergedDefaultSetUMIRNorm",PETSC_FALSE,&flag,&set);CHKERRQ(ierr); if (set && flag) {ierr = KSPConvergedDefaultSetUMIRNorm(ksp);CHKERRQ(ierr);} ierr = PetscOptionsBool("-ksp_initial_guess_nonzero","Use the contents of the solution vector for initial guess","KSPSetInitialNonzero",ksp->guess_zero ? PETSC_FALSE : PETSC_TRUE,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetInitialGuessNonzero(ksp,flag);CHKERRQ(ierr); } ierr = PCGetReusePreconditioner(ksp->pc,&reuse);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one ","KSPReusePreconditioner",reuse,&reuse,NULL);CHKERRQ(ierr); ierr = KSPSetReusePreconditioner(ksp,reuse);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);CHKERRQ(ierr); ierr = PetscOptionsFList("-ksp_guess_type","Initial guess in Krylov method",NULL,KSPGuessList,NULL,guesstype,256,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPGetGuess(ksp,&ksp->guess);CHKERRQ(ierr); ierr = KSPGuessSetType(ksp->guess,guesstype);CHKERRQ(ierr); ierr = KSPGuessSetFromOptions(ksp->guess);CHKERRQ(ierr); } else { /* old option for KSP */ nmax = 2; ierr = PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);CHKERRQ(ierr); if (flag) { if (nmax != 2) SETERRQ(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments"); ierr = KSPSetUseFischerGuess(ksp,model[0],model[1]);CHKERRQ(ierr); } } ierr = PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,3,"default",&indx,&flg);CHKERRQ(ierr); if (flg) { switch (indx) { case 0: ierr = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr); ierr = KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr); break; case 1: ierr = KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL);CHKERRQ(ierr); break; case 2: ierr = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr); ierr = KSPSetConvergenceTest(ksp,KSPLSQRConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr); break; } } ierr = KSPSetUpNorms_Private(ksp,PETSC_FALSE,&normtype,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnum("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,(PetscEnum)normtype,(PetscEnum*)&normtype,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetNormType(ksp,normtype);CHKERRQ(ierr); } ierr = PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",ksp->lagnorm,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetLagNorm(ksp,flag);CHKERRQ(ierr); } ierr = KSPGetDiagonalScale(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetDiagonalScale(ksp,flag);CHKERRQ(ierr); } ierr = KSPGetDiagonalScaleFix(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetDiagonalScaleFix(ksp,flag);CHKERRQ(ierr); } ierr = PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver matrix","MatSetNullSpace",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); if (set && flg) { MatNullSpace nsp; Mat Amat; ierr = MatNullSpaceCreate(comm,PETSC_TRUE,0,NULL,&nsp);CHKERRQ(ierr); ierr = PCGetOperators(ksp->pc,&Amat,NULL);CHKERRQ(ierr); if (Amat) { ierr = MatSetNullSpace(Amat,nsp);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&nsp);CHKERRQ(ierr); } else SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot set nullspace, matrix has not yet been provided"); } ierr = PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); /* -----------------------------------------------------------------------*/ /* Cancels all monitors hardwired into code before call to KSPSetFromOptions() */ if (set && flg) { ierr = KSPMonitorCancel(ksp);CHKERRQ(ierr); } ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor","Monitor the (preconditioned) residual norm","KSPMonitorDefault",KSPMonitorDefault);CHKERRQ(ierr); ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_range","Monitor the percentage of large entries in the residual","KSPMonitorRange",KSPMonitorRange);CHKERRQ(ierr); ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_true_residual","Monitor the unprecondiitoned residual norm","KSPMOnitorTrueResidual",KSPMonitorTrueResidualNorm);CHKERRQ(ierr); ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_max","Monitor the maximum norm of the residual","KSPMonitorTrueResidualMaxNorm",KSPMonitorTrueResidualMaxNorm);CHKERRQ(ierr); ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorDefaultShort",KSPMonitorDefaultShort);CHKERRQ(ierr); ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_solution","Monitor the solution","KSPMonitorSolution",KSPMonitorSolution);CHKERRQ(ierr); ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSingularValue",KSPMonitorSingularValue);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,((PetscObject)ksp)->prefix,"-ksp_monitor_singular_value",&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); } ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flag);CHKERRQ(ierr); if (flg || flag) { /* A hack for using dynamic tolerance in preconditioner */ ierr = PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { KSPDynTolCtx *scale; ierr = PetscMalloc1(1,&scale);CHKERRQ(ierr); scale->bnrm = -1.0; scale->coef = 1.0; ierr = PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",scale->coef,&scale->coef,&flg);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);CHKERRQ(ierr); } } /* Calls Python function */ ierr = PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ksp,monfilename);CHKERRQ(ierr);} /* Graphically plots preconditioned residual norm */ ierr = PetscOptionsBool("-ksp_monitor_lg_residualnorm","Monitor graphically preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); if (set && flg) { PetscDrawLG ctx; ierr = KSPMonitorLGResidualNormCreate(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr); } /* Graphically plots preconditioned and true residual norm */ ierr = PetscOptionsBool("-ksp_monitor_lg_true_residualnorm","Monitor graphically true residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); if (set && flg) { PetscDrawLG ctx; ierr = KSPMonitorLGTrueResidualNormCreate(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr); } /* Graphically plots preconditioned residual norm and range of residual element values */ ierr = PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); if (set && flg) { PetscViewer ctx; ierr = PetscViewerDrawOpen(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } /* TODO Do these show up in help? */ ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view", &ksp->viewer, &ksp->format, &ksp->view);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pre", &ksp->viewerPre, &ksp->formatPre, &ksp->viewPre);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_converged_reason", &ksp->viewerReason, &ksp->formatReason, &ksp->viewReason);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat", &ksp->viewerMat, &ksp->formatMat, &ksp->viewMat);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat", &ksp->viewerPMat, &ksp->formatPMat, &ksp->viewPMat);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs", &ksp->viewerRhs, &ksp->formatRhs, &ksp->viewRhs);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution", &ksp->viewerSol, &ksp->formatSol, &ksp->viewSol);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit", &ksp->viewerMatExp, &ksp->formatMatExp, &ksp->viewMatExp);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues", &ksp->viewerEV, &ksp->formatEV, &ksp->viewEV);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_singularvalues", &ksp->viewerSV, &ksp->formatSV, &ksp->viewSV);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues_explicit", &ksp->viewerEVExp, &ksp->formatEVExp, &ksp->viewEVExp);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual", &ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp, &ksp->formatPOpExp, &ksp->viewPOpExp);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale", &ksp->viewerDScale, &ksp->formatDScale, &ksp->viewDScale);CHKERRQ(ierr); /* Deprecated options */ if (!ksp->viewEV) {ierr = PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues", &ksp->viewerEV, &ksp->formatEV, &ksp->viewEV);CHKERRQ(ierr);} if (!ksp->viewEV) { ierr = PetscOptionsName("-ksp_plot_eigenvalues", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw]", "KSPView", &ksp->viewEV);CHKERRQ(ierr); if (ksp->viewEV) { ksp->formatEV = PETSC_VIEWER_DEFAULT; ksp->viewerEV = PETSC_VIEWER_DRAW_(comm); ierr = PetscObjectReference((PetscObject) ksp->viewerEV);CHKERRQ(ierr); } } if (!ksp->viewEV) { ierr = PetscOptionsName("-ksp_plot_eigencontours", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw::draw_contour]", "KSPView", &ksp->viewEV);CHKERRQ(ierr); if (ksp->viewEV) { ksp->formatEV = PETSC_VIEWER_DRAW_CONTOUR; ksp->viewerEV = PETSC_VIEWER_DRAW_(comm); ierr = PetscObjectReference((PetscObject) ksp->viewerEV);CHKERRQ(ierr); } } if (!ksp->viewEVExp) {ierr = PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues_explicitly", &ksp->viewerEVExp, &ksp->formatEVExp, &ksp->viewEVExp);CHKERRQ(ierr);} if (!ksp->viewEVExp) { ierr = PetscOptionsName("-ksp_plot_eigenvalues_explicitly", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues_explicit draw]", "KSPView", &ksp->viewEVExp);CHKERRQ(ierr); if (ksp->viewEVExp) { ksp->formatEVExp = PETSC_VIEWER_DEFAULT; ksp->viewerEVExp = PETSC_VIEWER_DRAW_(comm); ierr = PetscObjectReference((PetscObject) ksp->viewerEVExp);CHKERRQ(ierr); } } if (!ksp->viewSV) {ierr = PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_singularvalues", &ksp->viewerSV, &ksp->formatSV, &ksp->viewSV);CHKERRQ(ierr);} if (!ksp->viewFinalRes) {ierr = PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_final_residual", &ksp->viewerFinalRes, &ksp->formatFinalRes, &ksp->viewFinalRes);CHKERRQ(ierr);} #if defined(PETSC_HAVE_SAWS) /* Publish convergence information using AMS */ ierr = PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); if (set && flg) { void *ctx; ierr = KSPMonitorSAWsCreate(ksp,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);CHKERRQ(ierr); ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); } #endif /* -----------------------------------------------------------------------*/ ierr = KSPSetUpNorms_Private(ksp,PETSC_FALSE,NULL,&pcside);CHKERRQ(ierr); ierr = PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); if (flg) {ierr = KSPSetPCSide(ksp,pcside);CHKERRQ(ierr);} ierr = PetscOptionsBool("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",ksp->calc_sings,&flg,&set);CHKERRQ(ierr); if (set) { ierr = KSPSetComputeSingularValues(ksp,flg);CHKERRQ(ierr); } ierr = PetscOptionsBool("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",ksp->calc_sings,&flg,&set);CHKERRQ(ierr); if (set) { ierr = KSPSetComputeSingularValues(ksp,flg);CHKERRQ(ierr); } ierr = PetscOptionsBool("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); if (set) { ierr = KSPSetComputeSingularValues(ksp,flg);CHKERRQ(ierr); } #if defined(PETSC_HAVE_SAWS) { PetscBool set; flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);CHKERRQ(ierr); if (set) { ierr = PetscObjectSAWsSetBlock((PetscObject)ksp,flg);CHKERRQ(ierr); } } #endif if (ksp->ops->setfromoptions) { ierr = (*ksp->ops->setfromoptions)(PetscOptionsObject,ksp);CHKERRQ(ierr); } skipoptions: /* process any options handlers added with PetscObjectAddOptionsHandler() */ ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ksp);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ksp->setfromoptionscalled++; PetscFunctionReturn(0); }