Dear Jose, will you please also take a look at the SVD code for smallest singular value? It seems work except the time consuming SVDCyclicSetExplicitMatrix routine. However, I wonder if there exist some more clever method.
// SVD solver for smallest singular value SVD svd_s; EPS eps_s; ST st_s; KSP ksp_s; PC pc_s; PetscErrorCode ierr; // Create singular value solver context ierr = SVDCreate(PETSC_COMM_WORLD, &svd_s); // Set operator ierr = SVDSetOperator(svd_s, J); // small singular value use eigen value solver on Cyclic Matrix ierr = SVDSetWhichSingularTriplets(svd_s, SVD_SMALLEST); ierr = SVDSetType(svd_s, SVDCYCLIC); ierr = SVDCyclicSetExplicitMatrix(svd_s, PETSC_TRUE); // <-----time consuming // shift-and-invert spectral transformation to enhance convergence of eigenvalues near zero ierr = SVDCyclicGetEPS(svd_s, &eps_s); ierr = EPSSetType(eps_s, EPSKRYLOVSCHUR); ierr = EPSGetST(eps_s, &st_s); ierr = STSetType(st_s, STSINVERT); ierr = STGetKSP(st_s, &ksp_s); ierr = KSPGetPC(ksp_s, &pc_s); // since we have to deal with bad conditioned problem, we choose direct solver whenever possible // direct solver as preconditioner ierr = KSPSetType (ksp_s, (char*) KSPGMRES); assert(!ierr); // superlu which use static pivot seems very stable ierr = PCSetType (pc_s, (char*) PCLU); assert(!ierr); ierr = PCFactorSetMatSolverPackage (pc_s, "superlu"); assert(!ierr); // Set solver parameters at runtime ierr = SVDSetFromOptions(svd_s); assert(!ierr); ierr = SVDSetUp(svd_s); assert(!ierr); PetscReal sigma_large=1, sigma_small=1; PetscInt nconv; PetscReal error; // find the smallest singular value SVDSolve(svd_s);
