Esempio n. 1
0
PetscErrorCode BSSCR_KSPConverged(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *cctx)
{
  PetscErrorCode           ierr;
#if(PETSC_VERSION_MAJOR == 3)
  BSSCR_KSPConverged_Ctx  *ctx = (BSSCR_KSPConverged_Ctx *)cctx;
  KSP_BSSCR               *bsscr = ctx->bsscr;
#else
  KSP_BSSCR               *bsscr = (KSP_BSSCR*)cctx;
#endif


  PetscFunctionBegin;
#if ( (PETSC_VERSION_MAJOR == 3) && (PETSC_VERSION_MINOR >=5 ) )
  ierr = KSPConvergedDefault(ksp,n,rnorm,reason,ctx->ctx);CHKERRQ(ierr);
#endif
#if ( (PETSC_VERSION_MAJOR == 3) && (PETSC_VERSION_MINOR <=4 ) )
  ierr = KSPDefaultConverged(ksp,n,rnorm,reason,ctx->ctx);CHKERRQ(ierr);
#endif
#if ( PETSC_VERSION_MAJOR < 3)
  ierr = KSPDefaultConverged(ksp,n,rnorm,reason,cctx);CHKERRQ(ierr);
#endif
  if (*reason) {
    ierr = PetscInfo2(ksp,"default convergence test KSP iterations=%D, rnorm=%G\n",n,rnorm);CHKERRQ(ierr);
  }
  if(ksp->its < bsscr->min_it){
      ksp->reason          = KSP_CONVERGED_ITERATING;
  }
  PetscFunctionReturn(0);
}
Esempio n. 2
0
/*@C
   KSPLSQRDefaultConverged - Determines convergence of the LSQR Krylov method. This calls KSPConvergedDefault() and if that does not determine convergence then checks
      convergence for the least squares problem.

   Collective on KSP

   Input Parameters:
+  ksp   - iterative context
.  n     - iteration number
.  rnorm - 2-norm residual value (may be estimated)
-  ctx - convergence context which must be created by KSPConvergedDefaultCreate()

   reason is set to:
+   positive - if the iteration has converged;
.   negative - if residual norm exceeds divergence threshold;
-   0 - otherwise.

   Notes:
      Possible convergence for the least squares problem (which is based on the residual of the normal equations) are KSP_CONVERGED_RTOL_NORMAL norm and KSP_CONVERGED_ATOL_NORMAL.

   Level: intermediate

.keywords: KSP, default, convergence, residual

.seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPConvergedSkip(), KSPConvergedReason, KSPGetConvergedReason(),
          KSPConvergedDefaultSetUIRNorm(), KSPConvergedDefaultSetUMIRNorm(), KSPConvergedDefaultCreate(), KSPConvergedDefaultDestroy(), KSPConvergedDefault()
@*/
PetscErrorCode  KSPLSQRDefaultConverged(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx)
{
  PetscErrorCode ierr;
  KSP_LSQR       *lsqr = (KSP_LSQR*)ksp->data;

  PetscFunctionBegin;
  ierr = KSPConvergedDefault(ksp,n,rnorm,reason,ctx);CHKERRQ(ierr);
  if (!n || *reason) PetscFunctionReturn(0);
  if (lsqr->arnorm/lsqr->rhs_norm < ksp->rtol) *reason = KSP_CONVERGED_RTOL_NORMAL;
  if (lsqr->arnorm < ksp->abstol) *reason = KSP_CONVERGED_ATOL_NORMAL;
  PetscFunctionReturn(0);
}
Esempio n. 3
0
/*
   This convergence test determines if the two norm of the
   solution lies outside the trust region, if so it halts.
*/
static PetscErrorCode SNESTR_KSPConverged_Private(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *cctx)
{
  SNES_TR_KSPConverged_Ctx *ctx = (SNES_TR_KSPConverged_Ctx*)cctx;
  SNES                     snes = ctx->snes;
  SNES_NEWTONTR            *neP = (SNES_NEWTONTR*)snes->data;
  Vec                      x;
  PetscReal                nrm;
  PetscErrorCode           ierr;

  PetscFunctionBegin;
  ierr = KSPConvergedDefault(ksp,n,rnorm,reason,ctx->ctx);CHKERRQ(ierr);
  if (*reason) {
    ierr = PetscInfo2(snes,"default convergence test KSP iterations=%D, rnorm=%g\n",n,(double)rnorm);CHKERRQ(ierr);
  }
  /* Determine norm of solution */
  ierr = KSPBuildSolution(ksp,0,&x);CHKERRQ(ierr);
  ierr = VecNorm(x,NORM_2,&nrm);CHKERRQ(ierr);
  if (nrm >= neP->delta) {
    ierr    = PetscInfo2(snes,"Ending linear iteration early, delta=%g, length=%g\n",(double)neP->delta,(double)nrm);CHKERRQ(ierr);
    *reason = KSP_CONVERGED_STEP_LENGTH;
  }
  PetscFunctionReturn(0);
}
Esempio n. 4
0
PetscErrorCode petscConverged(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason * reason, void * ctx)
{
  // Cast the context pointer coming from PETSc to an FEProblem& and
  // get a reference to the System from it.
  FEProblem & problem = *static_cast<FEProblem *>(ctx);

  // Let's be nice and always check PETSc error codes.
  PetscErrorCode ierr = 0;

  // We want the default behavior of the KSPDefaultConverged test, but
  // we don't want PETSc to die in that function with a CHKERRQ
  // call... that is probably extremely unlikely/impossible, but just
  // to be on the safe side, we push a different error handler before
  // calling KSPDefaultConverged().
  ierr = PetscPushErrorHandler(PetscReturnErrorHandler, /*void* ctx=*/ PETSC_NULL);
  CHKERRABORT(problem.comm().get(),ierr);

#if PETSC_VERSION_LESS_THAN(3,0,0)
  // Prior to PETSc 3.0.0, you could call KSPDefaultConverged with a NULL context
  // pointer, as it was unused.
  KSPDefaultConverged(ksp, n, rnorm, reason, PETSC_NULL);
#elif PETSC_RELEASE_LESS_THAN(3,5,0)
  // As of PETSc 3.0.0, you must call KSPDefaultConverged with a
  // non-NULL context pointer which must be created with
  // KSPDefaultConvergedCreate(), and destroyed with
  // KSPDefaultConvergedDestroy().
  void* default_ctx = NULL;
  KSPDefaultConvergedCreate(&default_ctx);
  KSPDefaultConverged(ksp, n, rnorm, reason, default_ctx);
  KSPDefaultConvergedDestroy(default_ctx);
#else
  // As of PETSc 3.5.0, use KSPConvergedDefaultXXX
  void* default_ctx = NULL;
  KSPConvergedDefaultCreate(&default_ctx);
  KSPConvergedDefault(ksp, n, rnorm, reason, default_ctx);
  KSPConvergedDefaultDestroy(default_ctx);
#endif

  // Pop the Error handler we pushed on the stack to go back
  // to default PETSc error handling behavior.
  ierr = PetscPopErrorHandler();
  CHKERRABORT(problem.comm().get(),ierr);

  // Get tolerances from the KSP object
  PetscReal rtol = 0.;
  PetscReal atol = 0.;
  PetscReal dtol = 0.;
  PetscInt maxits = 0;
  ierr = KSPGetTolerances(ksp, &rtol, &atol, &dtol, &maxits);
  CHKERRABORT(problem.comm().get(),ierr);

  // Now do some additional MOOSE-specific tests...
  std::string msg;
  MooseLinearConvergenceReason moose_reason = problem.checkLinearConvergence(msg, n, rnorm, rtol, atol, dtol, maxits);

  switch (moose_reason)
  {
  case MOOSE_CONVERGED_RTOL:
    *reason = KSP_CONVERGED_RTOL;
    break;

  case MOOSE_CONVERGED_ITS:
    *reason = KSP_CONVERGED_ITS;
    break;

  default:
  {
    // If it's not either of the two specific cases we handle, just go
    // with whatever PETSc decided in KSPDefaultConverged.
    break;
  }
  }

  return 0;
}
Esempio n. 5
0
File: tsirm.c Progetto: petsc/petsc
PetscErrorCode KSPSolve_TSIRM(KSP ksp)
{
    PetscErrorCode ierr;
    KSP_TSIRM      *tsirm = (KSP_TSIRM*)ksp->data;
    KSP            sub_ksp;
    PC             pc;
    Mat            AS;
    Vec            x,b;
    PetscScalar    *array;
    PetscReal      norm = 20;
    PetscInt       i,*ind_row,first_iteration = 1,its = 0,total = 0,col = 0;
    PetscInt       restart = 30;
    KSP            ksp_min;  /* KSP for minimization */
    PC             pc_min;    /* PC for minimization */

    PetscFunctionBegin;
    x = ksp->vec_sol; /* Solution vector        */
    b = ksp->vec_rhs; /* Right-hand side vector */

    /* Row indexes (these indexes are global) */
    ierr = PetscMalloc1(tsirm->Iend-tsirm->Istart,&ind_row);
    CHKERRQ(ierr);
    for (i=0; i<tsirm->Iend-tsirm->Istart; i++) ind_row[i] = i+tsirm->Istart;

    /* Inner solver */
    ierr = KSPGetPC(ksp,&pc);
    CHKERRQ(ierr);
    ierr = PCKSPGetKSP(pc,&sub_ksp);
    CHKERRQ(ierr);
    ierr = KSPSetTolerances(sub_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,restart);
    CHKERRQ(ierr);

    /* previously it seemed good but with SNES it seems not good... */
    ierr = KSP_MatMult(sub_ksp,tsirm->A,x,tsirm->r);
    CHKERRQ(ierr);
    ierr = VecAXPY(tsirm->r,-1,b);
    CHKERRQ(ierr);
    ierr = VecNorm(tsirm->r,NORM_2,&norm);
    CHKERRQ(ierr);
    ksp->its = 0;
    ierr = KSPConvergedDefault(ksp,ksp->its,norm,&ksp->reason,ksp->cnvP);
    CHKERRQ(ierr);
    ierr = KSPSetInitialGuessNonzero(sub_ksp,PETSC_TRUE);
    CHKERRQ(ierr);
    do {
        for (col=0; col<tsirm->size_ls && ksp->reason==0; col++) {
            /* Solve (inner iteration) */
            ierr = KSPSolve(sub_ksp,b,x);
            CHKERRQ(ierr);
            ierr = KSPGetIterationNumber(sub_ksp,&its);
            CHKERRQ(ierr);
            total += its;

            /* Build S^T */
            ierr = VecGetArray(x,&array);
            CHKERRQ(ierr);
            ierr = MatSetValues(tsirm->S,tsirm->Iend-tsirm->Istart,ind_row,1,&col,array,INSERT_VALUES);
            CHKERRQ(ierr);
            ierr = VecRestoreArray(x,&array);
            CHKERRQ(ierr);

            ierr = KSPGetResidualNorm(sub_ksp,&norm);
            CHKERRQ(ierr);
            ksp->rnorm = norm;
            ksp->its ++;
            ierr = KSPConvergedDefault(ksp,ksp->its,norm,&ksp->reason,ksp->cnvP);
            CHKERRQ(ierr);
            ierr = KSPMonitor(ksp,ksp->its,norm);
            CHKERRQ(ierr);
        }

        /* Minimization step */
        if (!ksp->reason) {
            ierr = MatAssemblyBegin(tsirm->S,MAT_FINAL_ASSEMBLY);
            CHKERRQ(ierr);
            ierr = MatAssemblyEnd(tsirm->S,MAT_FINAL_ASSEMBLY);
            CHKERRQ(ierr);
            if (first_iteration) {
                ierr = MatMatMult(tsirm->A,tsirm->S,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AS);
                CHKERRQ(ierr);
                first_iteration = 0;
            } else {
                ierr = MatMatMult(tsirm->A,tsirm->S,MAT_REUSE_MATRIX,PETSC_DEFAULT,&AS);
                CHKERRQ(ierr);
            }

            /* CGLS or LSQR method to minimize the residuals*/

            ierr = KSPCreate(PETSC_COMM_WORLD,&ksp_min);
            CHKERRQ(ierr);
            if (tsirm->cgls) {
                ierr = KSPSetType(ksp_min,KSPCGLS);
                CHKERRQ(ierr);
            } else {
                ierr = KSPSetType(ksp_min,KSPLSQR);
                CHKERRQ(ierr);
            }
            ierr = KSPSetOperators(ksp_min,AS,AS);
            CHKERRQ(ierr);
            ierr = KSPSetTolerances(ksp_min,tsirm->tol_ls,PETSC_DEFAULT,PETSC_DEFAULT,tsirm->maxiter_ls);
            CHKERRQ(ierr);
            ierr = KSPGetPC(ksp_min,&pc_min);
            CHKERRQ(ierr);
            ierr = PCSetType(pc_min,PCNONE);
            CHKERRQ(ierr);
            ierr = KSPSolve(ksp_min,b,tsirm->Alpha);
            CHKERRQ(ierr);    /* Find Alpha such that ||AS Alpha = b|| */
            ierr = KSPDestroy(&ksp_min);
            CHKERRQ(ierr);
            /* Apply minimization */
            ierr = MatMult(tsirm->S,tsirm->Alpha,x);
            CHKERRQ(ierr); /* x = S * Alpha */
        }
    } while (ksp->its<ksp->max_it && !ksp->reason);
    ierr = MatDestroy(&AS);
    CHKERRQ(ierr);
    ierr = PetscFree(ind_row);
    CHKERRQ(ierr);
    ksp->its = total;
    PetscFunctionReturn(0);
}
Esempio n. 6
0
PETSC_EXTERN void kspconvergeddefault_(KSP *ksp,PetscInt *n,PetscReal *rnorm,KSPConvergedReason *flag,void *dummy,PetscErrorCode *ierr)
{
  CHKFORTRANNULLOBJECT(dummy);
  *ierr = KSPConvergedDefault(*ksp,*n,*rnorm,flag,dummy);
}