PetscErrorCode KSPMonitorLGTrueResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscObject *objs) { PetscDrawLG lg = (PetscDrawLG) objs[0]; PetscReal x[2],y[2],scnorm; PetscErrorCode ierr; PetscMPIInt rank; Vec resid,work; PetscFunctionBegin; ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ksp),&rank);CHKERRQ(ierr); if (!rank) { if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} x[0] = x[1] = (PetscReal) n; if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm); else y[0] = -15.0; } ierr = VecDuplicate(ksp->vec_rhs,&work);CHKERRQ(ierr); ierr = KSPBuildResidual(ksp,0,work,&resid);CHKERRQ(ierr); ierr = VecNorm(resid,NORM_2,&scnorm);CHKERRQ(ierr); ierr = VecDestroy(&work);CHKERRQ(ierr); if (!rank) { if (scnorm > 0.0) y[1] = PetscLog10Real(scnorm); else y[1] = -15.0; ierr = PetscDrawLGAddPoint(lg,x,y);CHKERRQ(ierr); if (n <= 20 || (n % 3)) { ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
/*@C KSPMonitorTrueResidualMaxNorm - Prints the true residual max norm as well as the preconditioned residual norm at each iteration of an iterative solver. Collective on KSP Input Parameters: + ksp - iterative context . n - iteration number . rnorm - norm (preconditioned) residual value (may be estimated). - dummy - an ASCII viewer Options Database Key: . -ksp_monitor_max - Activates KSPMonitorTrueResidualMaxNorm() Notes: This could be implemented (better) with a flag in ksp. Level: intermediate .keywords: KSP, default, monitor, residual .seealso: KSPMonitorSet(), KSPMonitorDefault(), KSPMonitorLGResidualNormCreate(),KSPMonitorTrueResidualNorm() @*/ PetscErrorCode KSPMonitorTrueResidualMaxNorm(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy) { PetscErrorCode ierr; Vec resid; PetscReal truenorm,bnorm; PetscViewer viewer = (PetscViewer)dummy; char normtype[256]; PetscFunctionBegin; PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr); if (n == 0 && ((PetscObject)ksp)->prefix) { ierr = PetscViewerASCIIPrintf(viewer," Residual norms (max) for %s solve.\n",((PetscObject)ksp)->prefix);CHKERRQ(ierr); } ierr = KSPBuildResidual(ksp,NULL,NULL,&resid);CHKERRQ(ierr); ierr = VecNorm(resid,NORM_INFINITY,&truenorm);CHKERRQ(ierr); ierr = VecDestroy(&resid);CHKERRQ(ierr); ierr = VecNorm(ksp->vec_rhs,NORM_INFINITY,&bnorm);CHKERRQ(ierr); ierr = PetscStrncpy(normtype,KSPNormTypes[ksp->normtype],sizeof(normtype));CHKERRQ(ierr); ierr = PetscStrtolower(normtype);CHKERRQ(ierr); /* ierr = PetscViewerASCIIPrintf(viewer,"%3D KSP %s resid norm %14.12e true resid norm %14.12e ||r(i)||_inf/||b||_inf %14.12e\n",n,normtype,(double)rnorm,(double)truenorm,(double)(truenorm/bnorm));CHKERRQ(ierr); */ ierr = PetscViewerASCIIPrintf(viewer,"%3D KSP true resid max norm %14.12e ||r(i)||/||b|| %14.12e\n",n,(double)truenorm,(double)(truenorm/bnorm));CHKERRQ(ierr); ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode BSSCR_KSPNorm2RawMonitor(KSP ksp,PetscInt n,PetscReal rnorm, void *dummy) { PetscErrorCode ierr; PetscViewerASCIIMonitor viewer; PetscReal R_norm2; Vec R, work, w1,w2; PetscFunctionBegin; ierr = VecDuplicate(ksp->vec_rhs,&work);CHKERRQ(ierr); ierr = VecDuplicate(ksp->vec_rhs,&w1);CHKERRQ(ierr); ierr = VecDuplicate(ksp->vec_rhs,&w2);CHKERRQ(ierr); KSPBuildResidual( ksp, w1,w2, &R ); VecNorm( R, NORM_2, &R_norm2 ); ierr = PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,"stdout",0,&viewer); CHKERRQ(ierr); ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual Norm2raw %14.12e (%s) \n", n, R_norm2, ((PetscObject)ksp)->prefix ? ((PetscObject)ksp)->prefix: ""); CHKERRQ(ierr); ierr = PetscViewerASCIIMonitorDestroy(viewer); CHKERRQ(ierr); Stg_VecDestroy(&work); Stg_VecDestroy(&w1); Stg_VecDestroy(&w2); PetscFunctionReturn(0); }
PetscErrorCode KSPMonitorRange_Private(KSP ksp,PetscInt it,PetscReal *per) { PetscErrorCode ierr; Vec resid; PetscReal rmax,pwork; PetscInt i,n,N; const PetscScalar *r; PetscFunctionBegin; ierr = KSPBuildResidual(ksp,NULL,NULL,&resid); CHKERRQ(ierr); ierr = VecNorm(resid,NORM_INFINITY,&rmax); CHKERRQ(ierr); ierr = VecGetLocalSize(resid,&n); CHKERRQ(ierr); ierr = VecGetSize(resid,&N); CHKERRQ(ierr); ierr = VecGetArrayRead(resid,&r); CHKERRQ(ierr); pwork = 0.0; for (i=0; i<n; i++) pwork += (PetscAbsScalar(r[i]) > .20*rmax); ierr = VecRestoreArrayRead(resid,&r); CHKERRQ(ierr); ierr = VecDestroy(&resid); CHKERRQ(ierr); ierr = MPIU_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ksp)); CHKERRQ(ierr); *per = *per/N; PetscFunctionReturn(0); }
PetscErrorCode KSPMonitorLGTrueResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,void *ctx) { PetscDrawLG lg = (PetscDrawLG) ctx; PetscReal x[2],y[2],scnorm; Vec resid,work; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,4); if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} x[0] = x[1] = (PetscReal) n; if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm); else y[0] = -15.0; ierr = VecDuplicate(ksp->vec_rhs,&work);CHKERRQ(ierr); ierr = KSPBuildResidual(ksp,NULL,work,&resid);CHKERRQ(ierr); ierr = VecNorm(resid,NORM_2,&scnorm);CHKERRQ(ierr); ierr = VecDestroy(&work);CHKERRQ(ierr); if (scnorm > 0.0) y[1] = PetscLog10Real(scnorm); else y[1] = -15.0; ierr = PetscDrawLGAddPoint(lg,x,y);CHKERRQ(ierr); if (n <= 20 || !(n % 5)) { ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@C KSPMonitorTrueResidualNorm - Prints the true residual norm as well as the preconditioned residual norm at each iteration of an iterative solver. Collective on KSP Input Parameters: + ksp - iterative context . n - iteration number . rnorm - 2-norm (preconditioned) residual value (may be estimated). - dummy - unused monitor context Options Database Key: . -ksp_monitor_true_residual - Activates KSPMonitorTrueResidualNorm() Notes: When using right preconditioning, these values are equivalent. Level: intermediate .keywords: KSP, default, monitor, residual .seealso: KSPMonitorSet(), KSPMonitorDefault(), KSPMonitorLGResidualNormCreate(),KSPMonitorTrueResidualMaxNorm() @*/ PetscErrorCode KSPMonitorTrueResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy) { PetscErrorCode ierr; Vec resid; PetscReal truenorm,bnorm; PetscViewer viewer = (PetscViewer)dummy; char normtype[256]; PetscFunctionBegin; if (!viewer) { ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);CHKERRQ(ierr); } ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr); if (n == 0 && ((PetscObject)ksp)->prefix) { ierr = PetscViewerASCIIPrintf(viewer," Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);CHKERRQ(ierr); } ierr = KSPBuildResidual(ksp,NULL,NULL,&resid);CHKERRQ(ierr); ierr = VecNorm(resid,NORM_2,&truenorm);CHKERRQ(ierr); ierr = VecDestroy(&resid);CHKERRQ(ierr); ierr = VecNorm(ksp->vec_rhs,NORM_2,&bnorm);CHKERRQ(ierr); ierr = PetscStrncpy(normtype,KSPNormTypes[ksp->normtype],sizeof(normtype));CHKERRQ(ierr); ierr = PetscStrtolower(normtype);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%3D KSP %s resid norm %14.12e true resid norm %14.12e ||r(i)||/||b|| %14.12e\n",n,normtype,(double)rnorm,(double)truenorm,(double)(truenorm/bnorm));CHKERRQ(ierr); ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode BSSCR_KSPNormInfToNorm2Monitor(KSP ksp,PetscInt n,PetscReal rnorm, void *dummy) { PetscErrorCode ierr; PetscViewerASCIIMonitor viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)ksp)->comm); PetscReal R_normInf, R_norm2; PetscInt R_size; Vec R, work, w1, w2; PetscFunctionBegin; ierr = VecDuplicate(ksp->vec_rhs,&work);CHKERRQ(ierr); ierr = VecDuplicate(ksp->vec_rhs,&w1);CHKERRQ(ierr); ierr = VecDuplicate(ksp->vec_rhs,&w2);CHKERRQ(ierr); KSPBuildResidual( ksp, w1,w2, &R ); VecNorm( R, NORM_INFINITY, &R_normInf ); VecNorm( R, NORM_2, &R_norm2 ); VecGetSize( R, &R_size ); ierr = PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,"stdout",0,&viewer); CHKERRQ(ierr); if(R_norm2 == 0.0) { ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual Spikiness - INFINITY (%s) \n", n, ((PetscObject)ksp)->prefix ? ((PetscObject)ksp)->prefix: "" ); CHKERRQ(ierr); } else{ ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual Spikiness %14.12e (%s) Max / Rms \n", n, sqrt((double) R_size) * R_normInf / R_norm2, ((PetscObject)ksp)->prefix ? ((PetscObject)ksp)->prefix: ""); CHKERRQ(ierr); } ierr = PetscViewerASCIIMonitorDestroy(viewer); CHKERRQ(ierr); Stg_VecDestroy(&work); Stg_VecDestroy(&w1); Stg_VecDestroy(&w2); PetscFunctionReturn(0); }
PetscErrorCode BSSCR_KSPNormInfConverged(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx) { PetscErrorCode ierr; KSPPWConvergedCtx *cctx = (KSPPWConvergedCtx*)ctx; KSPNormType normtype; PetscReal min, max, R_max, R_min, R_Ninf; Vec R, work, w1,w2; PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_COOKIE,1); PetscValidPointer(reason,4); *reason = KSP_CONVERGED_ITERATING; ierr = VecDuplicate(ksp->vec_rhs,&work);CHKERRQ(ierr); ierr = VecDuplicate(ksp->vec_rhs,&w1);CHKERRQ(ierr); ierr = VecDuplicate(ksp->vec_rhs,&w2);CHKERRQ(ierr); KSPBuildResidual( ksp, w1,w2, &R ); VecNorm( R, NORM_INFINITY, &R_Ninf ); //PetscPrintf( PETSC_COMM_WORLD, "Norm inf convergence %s\n ", ksp->prefix); cctx->pointwise_max = R_Ninf; ierr = KSPGetNormType(ksp,&normtype); CHKERRQ(ierr); if (normtype == KSP_NORM_NO) Stg_SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Use BSSCR_KSPSkipConverged() with KSPNormType of KSP_NORM_NO"); if (!cctx) Stg_SETERRQ(PETSC_ERR_ARG_NULL,"Convergence context must have been created with BSSCR_KSPDefaultConvergedCreate()"); if (!n) { /* if user gives initial guess need to compute norm of b */ if (!ksp->guess_zero && !cctx->initialrtol) { PetscReal snorm; if (ksp->normtype == KSP_NORM_UNPRECONDITIONED || ksp->pc_side == PC_RIGHT) { ierr = PetscInfo(ksp,"user has provided nonzero initial guess, computing 2-norm of RHS\n"); CHKERRQ(ierr); ierr = VecNorm(ksp->vec_rhs,NORM_INFINITY,&snorm);CHKERRQ(ierr); /* <- b'*b */ PetscPrintf( PETSC_COMM_WORLD, "Non Zero Guess; RHS - %g\n", snorm); } else { Vec z; if (!cctx->work) { ierr = VecDuplicate(ksp->vec_rhs,&cctx->work);CHKERRQ(ierr); } z = cctx->work; ierr = KSP_PCApply(ksp,ksp->vec_rhs,z);CHKERRQ(ierr); if (ksp->normtype == KSP_NORM_PRECONDITIONED) { ierr = PetscInfo(ksp,"user has provided nonzero initial guess, computing 2-norm of preconditioned RHS\n");CHKERRQ(ierr); ierr = VecNorm(z,NORM_INFINITY,&snorm);CHKERRQ(ierr); /* dp <- b'*B'*B*b */ } else if (ksp->normtype == KSP_NORM_NATURAL) { PetscScalar norm; Vec bz; ierr = PetscInfo(ksp,"user has provided nonzero initial guess, computing natural norm of RHS\n");CHKERRQ(ierr); // ierr = VecDot(ksp->vec_rhs,z,&norm); // snorm = sqrt(PetscAbsScalar(norm)); /* dp <- b'*B*b */ VecDuplicate( z, &bz ); VecPointwiseMult( bz, ksp->vec_rhs, z ); ierr = VecNorm(bz,NORM_INFINITY,&snorm);CHKERRQ(ierr); Stg_VecDestroy(&bz); } } /* handle special case of zero RHS and nonzero guess */ if (!snorm) { ierr = PetscInfo(ksp,"Special case, user has provided nonzero initial guess and zero RHS\n");CHKERRQ(ierr); snorm = rnorm; } if (cctx->mininitialrtol) { ksp->rnorm0 = PetscMin(snorm,rnorm); } else { ksp->rnorm0 = snorm; } } else { ksp->rnorm0 = rnorm; } ksp->ttol = PetscMax(ksp->rtol*ksp->rnorm0,ksp->abstol); } // if (n <= ksp->chknorm) PetscFunctionReturn(0); if ( R_Ninf != R_Ninf ) { ierr = PetscInfo(ksp,"Linear solver has created a not a number (NaN) as the pointwise residual norm, declaring divergence \n");CHKERRQ(ierr); *reason = KSP_DIVERGED_NAN; } else if (R_Ninf <= ksp->ttol) { if (R_Ninf < ksp->abstol) { ierr = PetscInfo3(ksp,"Linear solver has converged. Pointwise residual %G is less than absolute tolerance %G at iteration %D\n",R_Ninf,ksp->abstol,n); CHKERRQ(ierr); *reason = KSP_CONVERGED_ATOL; } else { if (cctx->initialrtol) { ierr = PetscInfo4(ksp,"Linear solver has converged. Norm_infinity %G is less than relative tolerance %G times initial Norm_infinity %G at iteration %D\n",R_Ninf,ksp->rtol,ksp->rnorm0,n); CHKERRQ(ierr); } else { ierr = PetscInfo4(ksp,"Linear solver has converged. Norm_infinity %G is less than relative tolerance %G times initial norm_infinity right hand side %G at iteration %D\n",R_Ninf,ksp->rtol,ksp->rnorm0,n);CHKERRQ(ierr); } *reason = KSP_CONVERGED_RTOL; } } else if (R_Ninf >= ksp->divtol*ksp->rnorm0) { ierr = PetscInfo3(ksp,"Linear solver is diverging. Initial right hand size Norm_infinity value %G, current residual norm %G at iteration %D\n",ksp->rnorm0,R_Ninf,n);CHKERRQ(ierr); *reason = KSP_DIVERGED_DTOL; } /* trash all work vectors here */ Stg_VecDestroy(&work); Stg_VecDestroy(&w1); Stg_VecDestroy(&w2); PetscFunctionReturn(0); }