static PetscErrorCode SNESNEWTONLSCheckLocalMin_Private(SNES snes,Mat A,Vec F,PetscReal fnorm,PetscBool *ismin) { PetscReal a1; PetscErrorCode ierr; PetscBool hastranspose; Vec W; PetscFunctionBegin; *ismin = PETSC_FALSE; ierr = MatHasOperation(A,MATOP_MULT_TRANSPOSE,&hastranspose);CHKERRQ(ierr); ierr = VecDuplicate(F,&W);CHKERRQ(ierr); if (hastranspose) { /* Compute || J^T F|| */ ierr = MatMultTranspose(A,F,W);CHKERRQ(ierr); ierr = VecNorm(W,NORM_2,&a1);CHKERRQ(ierr); ierr = PetscInfo1(snes,"|| J^T F|| %14.12e near zero implies found a local minimum\n",(double)(a1/fnorm));CHKERRQ(ierr); if (a1/fnorm < 1.e-4) *ismin = PETSC_TRUE; } else { Vec work; PetscScalar result; PetscReal wnorm; ierr = VecSetRandom(W,NULL);CHKERRQ(ierr); ierr = VecNorm(W,NORM_2,&wnorm);CHKERRQ(ierr); ierr = VecDuplicate(W,&work);CHKERRQ(ierr); ierr = MatMult(A,W,work);CHKERRQ(ierr); ierr = VecDot(F,work,&result);CHKERRQ(ierr); ierr = VecDestroy(&work);CHKERRQ(ierr); a1 = PetscAbsScalar(result)/(fnorm*wnorm); ierr = PetscInfo1(snes,"(F^T J random)/(|| F ||*||random|| %14.12e near zero implies found a local minimum\n",(double)a1);CHKERRQ(ierr); if (a1 < 1.e-4) *ismin = PETSC_TRUE; } ierr = VecDestroy(&W);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode SNESNEWTONLSCheckResidual_Private(SNES snes,Mat A,Vec F,Vec X) { PetscReal a1,a2; PetscErrorCode ierr; PetscBool hastranspose; PetscFunctionBegin; ierr = MatHasOperation(A,MATOP_MULT_TRANSPOSE,&hastranspose);CHKERRQ(ierr); if (hastranspose) { Vec W1,W2; ierr = VecDuplicate(F,&W1);CHKERRQ(ierr); ierr = VecDuplicate(F,&W2);CHKERRQ(ierr); ierr = MatMult(A,X,W1);CHKERRQ(ierr); ierr = VecAXPY(W1,-1.0,F);CHKERRQ(ierr); /* Compute || J^T W|| */ ierr = MatMultTranspose(A,W1,W2);CHKERRQ(ierr); ierr = VecNorm(W1,NORM_2,&a1);CHKERRQ(ierr); ierr = VecNorm(W2,NORM_2,&a2);CHKERRQ(ierr); if (a1 != 0.0) { ierr = PetscInfo1(snes,"||J^T(F-Ax)||/||F-AX|| %14.12e near zero implies inconsistent rhs\n",(double)(a2/a1));CHKERRQ(ierr); } ierr = VecDestroy(&W1);CHKERRQ(ierr); ierr = VecDestroy(&W2);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/* PEPComputeScaleFactor - compute sfactor as described in [Betcke 2008]. */ PetscErrorCode PEPComputeScaleFactor(PEP pep) { PetscErrorCode ierr; PetscBool has0,has1,flg; PetscReal norm0,norm1; Mat T[2]; PEPBasis basis; PetscFunctionBegin; if (pep->scale==PEP_SCALE_NONE || pep->scale==PEP_SCALE_DIAGONAL) { /* no scalar scaling */ pep->sfactor = 1.0; PetscFunctionReturn(0); } if (pep->sfactor_set) PetscFunctionReturn(0); /* user provided value */ ierr = PEPGetBasis(pep,&basis);CHKERRQ(ierr); if (basis==PEP_BASIS_MONOMIAL) { ierr = STGetTransform(pep->st,&flg);CHKERRQ(ierr); if (flg) { ierr = STGetTOperators(pep->st,0,&T[0]);CHKERRQ(ierr); ierr = STGetTOperators(pep->st,pep->nmat-1,&T[1]);CHKERRQ(ierr); } else { T[0] = pep->A[0]; T[1] = pep->A[pep->nmat-1]; } if (pep->nmat>2) { ierr = MatHasOperation(T[0],MATOP_NORM,&has0);CHKERRQ(ierr); ierr = MatHasOperation(T[1],MATOP_NORM,&has1);CHKERRQ(ierr); if (has0 && has1) { ierr = MatNorm(T[0],NORM_INFINITY,&norm0);CHKERRQ(ierr); ierr = MatNorm(T[1],NORM_INFINITY,&norm1);CHKERRQ(ierr); pep->sfactor = PetscPowReal(norm0/norm1,1.0/(pep->nmat-1)); } else { pep->sfactor = 1.0; } } } else pep->sfactor = 1.0; PetscFunctionReturn(0); }
static PetscErrorCode PCApply_Eisenstat(PC pc,Vec x,Vec y) { PC_Eisenstat *eis = (PC_Eisenstat*)pc->data; PetscErrorCode ierr; PetscBool hasop; PetscFunctionBegin; if (eis->usediag) { ierr = MatHasOperation(pc->pmat,MATOP_MULT_DIAGONAL_BLOCK,&hasop);CHKERRQ(ierr); if (hasop) { ierr = MatMultDiagonalBlock(pc->pmat,x,y);CHKERRQ(ierr); } else { ierr = VecPointwiseMult(y,x,eis->diag);CHKERRQ(ierr); } } else {ierr = VecCopy(x,y);CHKERRQ(ierr);} PetscFunctionReturn(0); }
PetscErrorCode SNESLSCheckResidual_Private(SNES snes,Mat A,Vec F,Vec X,Vec W1,Vec W2) { PetscReal a1,a2; PetscErrorCode ierr; PetscTruth hastranspose; PetscFunctionBegin; ierr = MatHasOperation(A,MATOP_MULT_TRANSPOSE,&hastranspose);CHKERRQ(ierr); if (hastranspose) { ierr = MatMult(A,X,W1);CHKERRQ(ierr); ierr = VecAXPY(W1,-1.0,F);CHKERRQ(ierr); /* Compute || J^T W|| */ ierr = MatMultTranspose(A,W1,W2);CHKERRQ(ierr); ierr = VecNorm(W1,NORM_2,&a1);CHKERRQ(ierr); ierr = VecNorm(W2,NORM_2,&a2);CHKERRQ(ierr); if (a1 != 0.0) { ierr = PetscInfo1(snes,"||J^T(F-Ax)||/||F-AX|| %G near zero implies inconsistent rhs\n",a2/a1);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
/*@ MatHasOperation - Determines whether the given matrix supports the particular operation. Not Collective Input Parameters: + mat - the matrix - op - the operation, for example, MATOP_GET_DIAGONAL Output Parameter: . has - either PETSC_TRUE or PETSC_FALSE Level: advanced Notes: See the file include/petscmat.h for a complete list of matrix operations, which all have the form MATOP_<OPERATION>, where <OPERATION> is the name (in all capital letters) of the user-level routine. E.g., MatNorm() -> MATOP_NORM. .keywords: matrix, has, operation .seealso: MatCreateShell() @*/ PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) { PetscFunctionBegin; PetscValidHeaderSpecific(mat,MAT_CLASSID,1); PetscValidType(mat,1); PetscValidPointer(has,3); if (((void**)mat->ops)[op]) *has = PETSC_TRUE; else { if (op == MATOP_GET_SUBMATRIX) { PetscErrorCode ierr; PetscMPIInt size; ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); if (size == 1) { ierr = MatHasOperation(mat,MATOP_GET_SUBMATRICES,has);CHKERRQ(ierr); } else { *has = PETSC_FALSE; } } else { *has = PETSC_FALSE; } } PetscFunctionReturn(0); }
PetscErrorCode TestMatZeroRows(Mat A, Mat Afull, PetscBool squaretest, IS is, PetscScalar diag) { Mat B,Bcheck,B2 = NULL,lB; Vec x = NULL, b = NULL, b2 = NULL; ISLocalToGlobalMapping l2gr,l2gc; PetscReal error; char diagstr[16]; const PetscInt *idxs; PetscInt rst,ren,i,n,N,d; PetscMPIInt rank; PetscBool miss,haszerorows; PetscErrorCode ierr; PetscFunctionBeginUser; if (diag == 0.) { ierr = PetscStrcpy(diagstr,"zero");CHKERRQ(ierr); } else { ierr = PetscStrcpy(diagstr,"nonzero");CHKERRQ(ierr); } ierr = ISView(is,NULL);CHKERRQ(ierr); ierr = MatGetLocalToGlobalMapping(A,&l2gr,&l2gc);CHKERRQ(ierr); /* tests MatDuplicate and MatCopy */ if (diag == 0.) { ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); } else { ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&B);CHKERRQ(ierr); ierr = MatCopy(A,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); } ierr = MatISGetLocalMat(B,&lB);CHKERRQ(ierr); ierr = MatHasOperation(lB,MATOP_ZERO_ROWS,&haszerorows);CHKERRQ(ierr); if (squaretest && haszerorows) { ierr = MatCreateVecs(B,&x,&b);CHKERRQ(ierr); ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr); ierr = VecSetLocalToGlobalMapping(b,l2gr);CHKERRQ(ierr); ierr = VecSetLocalToGlobalMapping(x,l2gc);CHKERRQ(ierr); ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); ierr = VecSetRandom(b,NULL);CHKERRQ(ierr); /* mimic b[is] = x[is] */ ierr = VecDuplicate(b,&b2);CHKERRQ(ierr); ierr = VecSetLocalToGlobalMapping(b2,l2gr);CHKERRQ(ierr); ierr = VecCopy(b,b2);CHKERRQ(ierr); ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); ierr = VecGetSize(x,&N);CHKERRQ(ierr); for (i=0;i<n;i++) { if (0 <= idxs[i] && idxs[i] < N) { ierr = VecSetValue(b2,idxs[i],diag,INSERT_VALUES);CHKERRQ(ierr); ierr = VecSetValue(x,idxs[i],1.,INSERT_VALUES);CHKERRQ(ierr); } } ierr = VecAssemblyBegin(b2);CHKERRQ(ierr); ierr = VecAssemblyEnd(b2);CHKERRQ(ierr); ierr = VecAssemblyBegin(x);CHKERRQ(ierr); ierr = VecAssemblyEnd(x);CHKERRQ(ierr); ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); /* test ZeroRows on MATIS */ ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatZeroRows (diag %s)\n",diagstr);CHKERRQ(ierr); ierr = MatZeroRowsIS(B,is,diag,x,b);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatZeroRowsColumns (diag %s)\n",diagstr);CHKERRQ(ierr); ierr = MatZeroRowsColumnsIS(B2,is,diag,NULL,NULL);CHKERRQ(ierr); } else if (haszerorows) { /* test ZeroRows on MATIS */ ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatZeroRows (diag %s)\n",diagstr);CHKERRQ(ierr); ierr = MatZeroRowsIS(B,is,diag,NULL,NULL);CHKERRQ(ierr); b = b2 = x = NULL; } else { ierr = PetscPrintf(PETSC_COMM_WORLD,"Skipping MatZeroRows (diag %s)\n",diagstr);CHKERRQ(ierr); b = b2 = x = NULL; } if (squaretest && haszerorows) { ierr = VecAXPY(b2,-1.,b);CHKERRQ(ierr); ierr = VecNorm(b2,NORM_INFINITY,&error);CHKERRQ(ierr); if (error > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"ERROR IN ZEROROWS ON B %g (diag %s)",error,diagstr); } /* test MatMissingDiagonal */ ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatMissingDiagonal\n");CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MatMissingDiagonal(B,&miss,&d);CHKERRQ(ierr); ierr = MatGetOwnershipRange(B,&rst,&ren);CHKERRQ(ierr); ierr = PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD, "[%d] [%D,%D) Missing %d, row %D (diag %s)\n",rank,rst,ren,(int)miss,d,diagstr);CHKERRQ(ierr); ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIIPopSynchronized(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&b2);CHKERRQ(ierr); /* check the result of ZeroRows with that from MPIAIJ routines assuming that MatConvert_IS_XAIJ and MatZeroRows_MPIAIJ work fine */ if (haszerorows) { ierr = MatDuplicate(Afull,MAT_COPY_VALUES,&Bcheck);CHKERRQ(ierr); ierr = MatSetOption(Bcheck,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = MatZeroRowsIS(Bcheck,is,diag,NULL,NULL);CHKERRQ(ierr); ierr = CheckMat(B,Bcheck,PETSC_FALSE,"Zerorows");CHKERRQ(ierr); ierr = MatDestroy(&Bcheck);CHKERRQ(ierr); } ierr = MatDestroy(&B);CHKERRQ(ierr); if (B2) { /* test MatZeroRowsColumns */ ierr = MatDuplicate(Afull,MAT_COPY_VALUES,&B);CHKERRQ(ierr); ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = MatZeroRowsColumnsIS(B,is,diag,NULL,NULL);CHKERRQ(ierr); ierr = CheckMat(B2,B,PETSC_FALSE,"MatZeroRowsColumns");CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&B2);CHKERRQ(ierr); } PetscFunctionReturn(0); }
void PETSC_STDCALL mathasoperation_(Mat mat,MatOperation *op,PetscTruth *has, int *__ierr ){ *__ierr = MatHasOperation( (Mat)PetscToPointer((mat) ),*op,has); }
/*@ SVDSetUp - Sets up all the internal data structures necessary for the execution of the singular value solver. Collective on SVD Input Parameter: . svd - singular value solver context Level: advanced Notes: This function need not be called explicitly in most cases, since SVDSolve() calls it. It can be useful when one wants to measure the set-up time separately from the solve time. .seealso: SVDCreate(), SVDSolve(), SVDDestroy() @*/ PetscErrorCode SVDSetUp(SVD svd) { PetscErrorCode ierr; PetscBool expltrans,flg; PetscInt M,N,k; SlepcSC sc; Vec *T; PetscFunctionBegin; PetscValidHeaderSpecific(svd,SVD_CLASSID,1); if (svd->setupcalled) PetscFunctionReturn(0); ierr = PetscLogEventBegin(SVD_SetUp,svd,0,0,0);CHKERRQ(ierr); /* reset the convergence flag from the previous solves */ svd->reason = SVD_CONVERGED_ITERATING; /* Set default solver type (SVDSetFromOptions was not called) */ if (!((PetscObject)svd)->type_name) { ierr = SVDSetType(svd,SVDCROSS);CHKERRQ(ierr); } if (!svd->ds) { ierr = SVDGetDS(svd,&svd->ds);CHKERRQ(ierr); } ierr = DSReset(svd->ds);CHKERRQ(ierr); if (!((PetscObject)svd->rand)->type_name) { ierr = PetscRandomSetFromOptions(svd->rand);CHKERRQ(ierr); } /* check matrix */ if (!svd->OP) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_WRONGSTATE,"SVDSetOperator must be called first"); /* determine how to handle the transpose */ expltrans = PETSC_TRUE; if (svd->impltrans) expltrans = PETSC_FALSE; else { ierr = MatHasOperation(svd->OP,MATOP_TRANSPOSE,&flg);CHKERRQ(ierr); if (!flg) expltrans = PETSC_FALSE; else { ierr = PetscObjectTypeCompare((PetscObject)svd,SVDLAPACK,&flg);CHKERRQ(ierr); if (flg) expltrans = PETSC_FALSE; } } /* build transpose matrix */ ierr = MatDestroy(&svd->A);CHKERRQ(ierr); ierr = MatDestroy(&svd->AT);CHKERRQ(ierr); ierr = MatGetSize(svd->OP,&M,&N);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)svd->OP);CHKERRQ(ierr); if (expltrans) { if (M>=N) { svd->A = svd->OP; ierr = MatTranspose(svd->OP,MAT_INITIAL_MATRIX,&svd->AT);CHKERRQ(ierr); ierr = MatConjugate(svd->AT);CHKERRQ(ierr); } else { ierr = MatTranspose(svd->OP,MAT_INITIAL_MATRIX,&svd->A);CHKERRQ(ierr); ierr = MatConjugate(svd->A);CHKERRQ(ierr); svd->AT = svd->OP; } } else { if (M>=N) { svd->A = svd->OP; svd->AT = NULL; } else { svd->A = NULL; svd->AT = svd->OP; } } /* swap initial vectors if necessary */ if (M<N) { T=svd->ISL; svd->ISL=svd->IS; svd->IS=T; k=svd->ninil; svd->ninil=svd->nini; svd->nini=k; } if (svd->ncv > PetscMin(M,N)) svd->ncv = PetscMin(M,N); if (svd->nsv > PetscMin(M,N)) svd->nsv = PetscMin(M,N); if (svd->ncv && svd->nsv > svd->ncv) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"nsv bigger than ncv"); /* call specific solver setup */ ierr = (*svd->ops->setup)(svd);CHKERRQ(ierr); /* set tolerance if not yet set */ if (svd->tol==PETSC_DEFAULT) svd->tol = SLEPC_DEFAULT_TOL; /* fill sorting criterion context */ ierr = DSGetSlepcSC(svd->ds,&sc);CHKERRQ(ierr); sc->comparison = (svd->which==SVD_LARGEST)? SlepcCompareLargestReal: SlepcCompareSmallestReal; sc->comparisonctx = NULL; sc->map = NULL; sc->mapobj = NULL; /* process initial vectors */ if (svd->nini<0) { k = -svd->nini; if (k>svd->ncv) SETERRQ(PetscObjectComm((PetscObject)svd),1,"The number of initial vectors is larger than ncv"); ierr = BVInsertVecs(svd->V,0,&k,svd->IS,PETSC_TRUE);CHKERRQ(ierr); ierr = SlepcBasisDestroy_Private(&svd->nini,&svd->IS);CHKERRQ(ierr); svd->nini = k; } if (svd->ninil<0) { k = 0; if (svd->leftbasis) { k = -svd->ninil; if (k>svd->ncv) SETERRQ(PetscObjectComm((PetscObject)svd),1,"The number of left initial vectors is larger than ncv"); ierr = BVInsertVecs(svd->U,0,&k,svd->ISL,PETSC_TRUE);CHKERRQ(ierr); } else { ierr = PetscInfo(svd,"Ignoring initial left vectors\n");CHKERRQ(ierr); } ierr = SlepcBasisDestroy_Private(&svd->ninil,&svd->ISL);CHKERRQ(ierr); svd->ninil = k; } ierr = PetscLogEventEnd(SVD_SetUp,svd,0,0,0);CHKERRQ(ierr); svd->setupcalled = 1; PetscFunctionReturn(0); }
PetscErrorCode NEPSolve_RII(NEP nep) { PetscErrorCode ierr; Mat T=nep->function,Tp=nep->jacobian,Tsigma; Vec u,r=nep->work[0],delta=nep->work[1]; PetscScalar lambda,a1,a2; PetscReal relerr; PetscBool hascopy; KSPConvergedReason kspreason; PetscFunctionBegin; /* get initial approximation of eigenvalue and eigenvector */ ierr = NEPGetDefaultShift(nep,&lambda);CHKERRQ(ierr); if (!nep->nini) { ierr = BVSetRandomColumn(nep->V,0,nep->rand);CHKERRQ(ierr); } ierr = BVGetColumn(nep->V,0,&u);CHKERRQ(ierr); /* correct eigenvalue approximation: lambda = lambda - (u'*T*u)/(u'*Tp*u) */ ierr = NEPComputeFunction(nep,lambda,T,T);CHKERRQ(ierr); ierr = MatMult(T,u,r);CHKERRQ(ierr); ierr = VecDot(u,r,&a1);CHKERRQ(ierr); ierr = NEPApplyJacobian(nep,lambda,u,delta,r,Tp);CHKERRQ(ierr); ierr = VecDot(u,r,&a2);CHKERRQ(ierr); lambda = lambda - a1/a2; /* prepare linear solver */ ierr = MatDuplicate(T,MAT_COPY_VALUES,&Tsigma);CHKERRQ(ierr); ierr = KSPSetOperators(nep->ksp,Tsigma,Tsigma);CHKERRQ(ierr); /* Restart loop */ while (nep->reason == NEP_CONVERGED_ITERATING) { nep->its++; /* update preconditioner and set adaptive tolerance */ if (nep->lag && !(nep->its%nep->lag) && nep->its>2*nep->lag && relerr<1e-2) { ierr = MatHasOperation(T,MATOP_COPY,&hascopy);CHKERRQ(ierr); if (hascopy) { ierr = MatCopy(T,Tsigma,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); } else { ierr = MatDestroy(&Tsigma);CHKERRQ(ierr); ierr = MatDuplicate(T,MAT_COPY_VALUES,&Tsigma);CHKERRQ(ierr); } ierr = KSPSetOperators(nep->ksp,Tsigma,Tsigma);CHKERRQ(ierr); } if (!nep->cctol) { nep->ktol = PetscMax(nep->ktol/2.0,PETSC_MACHINE_EPSILON*10.0); ierr = KSPSetTolerances(nep->ksp,nep->ktol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); } /* form residual, r = T(lambda)*u */ ierr = NEPApplyFunction(nep,lambda,u,delta,r,T,T);CHKERRQ(ierr); /* convergence test */ ierr = VecNorm(r,NORM_2,&relerr);CHKERRQ(ierr); nep->errest[nep->nconv] = relerr; nep->eigr[nep->nconv] = lambda; if (relerr<=nep->rtol) { nep->nconv = nep->nconv + 1; nep->reason = NEP_CONVERGED_FNORM_RELATIVE; } ierr = NEPMonitor(nep,nep->its,nep->nconv,nep->eigr,nep->errest,1);CHKERRQ(ierr); if (!nep->nconv) { /* eigenvector correction: delta = T(sigma)\r */ ierr = NEP_KSPSolve(nep,r,delta);CHKERRQ(ierr); ierr = KSPGetConvergedReason(nep->ksp,&kspreason);CHKERRQ(ierr); if (kspreason<0) { ierr = PetscInfo1(nep,"iter=%D, linear solve failed, stopping solve\n",nep->its);CHKERRQ(ierr); nep->reason = NEP_DIVERGED_LINEAR_SOLVE; break; } /* update eigenvector: u = u - delta */ ierr = VecAXPY(u,-1.0,delta);CHKERRQ(ierr); /* normalize eigenvector */ ierr = VecNormalize(u,NULL);CHKERRQ(ierr); /* correct eigenvalue: lambda = lambda - (u'*T*u)/(u'*Tp*u) */ ierr = NEPApplyFunction(nep,lambda,u,delta,r,T,T);CHKERRQ(ierr); ierr = VecDot(u,r,&a1);CHKERRQ(ierr); ierr = NEPApplyJacobian(nep,lambda,u,delta,r,Tp);CHKERRQ(ierr); ierr = VecDot(u,r,&a2);CHKERRQ(ierr); lambda = lambda - a1/a2; } if (nep->its >= nep->max_it) nep->reason = NEP_DIVERGED_MAX_IT; } ierr = MatDestroy(&Tsigma);CHKERRQ(ierr); ierr = BVRestoreColumn(nep->V,0,&u);CHKERRQ(ierr); PetscFunctionReturn(0); }