예제 #1
0
PetscErrorCode PEPSetFromOptions_Linear(PEP pep)
{
  PetscErrorCode ierr;
  PetscBool      set,val;
  PetscInt       i;
  PEP_LINEAR     *ctx = (PEP_LINEAR*)pep->data;
  ST             st;

  PetscFunctionBegin;
  if (!ctx->eps) { ierr = PEPLinearGetEPS(pep,&ctx->eps);CHKERRQ(ierr); }
  ierr = EPSSetFromOptions(ctx->eps);CHKERRQ(ierr);
  ierr = PetscOptionsHead("PEP Linear Options");CHKERRQ(ierr);
  ierr = PetscOptionsInt("-pep_linear_cform","Number of the companion form","PEPLinearSetCompanionForm",ctx->cform,&i,&set);CHKERRQ(ierr);
  if (set) {
    ierr = PEPLinearSetCompanionForm(pep,i);CHKERRQ(ierr);
  }
  ierr = PetscOptionsBool("-pep_linear_explicitmatrix","Use explicit matrix in linearization","PEPLinearSetExplicitMatrix",ctx->explicitmatrix,&val,&set);CHKERRQ(ierr);
  if (set) {
    ierr = PEPLinearSetExplicitMatrix(pep,val);CHKERRQ(ierr);
  }
  if (!ctx->explicitmatrix) {
    /* use as default an ST with shell matrix and Jacobi */
    if (!ctx->eps) { ierr = PEPLinearGetEPS(pep,&ctx->eps);CHKERRQ(ierr); }
    ierr = EPSGetST(ctx->eps,&st);CHKERRQ(ierr);
    ierr = STSetMatMode(st,ST_MATMODE_SHELL);CHKERRQ(ierr);
  }
  ierr = PetscOptionsTail();CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
예제 #2
0
/*@
   EPSSetTarget - Sets the value of the target.

   Logically Collective on EPS

   Input Parameters:
+  eps    - eigensolver context
-  target - the value of the target

   Options Database Key:
.  -eps_target <scalar> - the value of the target

   Notes:
   The target is a scalar value used to determine the portion of the spectrum
   of interest. It is used in combination with EPSSetWhichEigenpairs().

   In the case of complex scalars, a complex value can be provided in the
   command line with [+/-][realnumber][+/-]realnumberi with no spaces, e.g.
   -eps_target 1.0+2.0i

   Level: beginner

.seealso: EPSGetTarget(), EPSSetWhichEigenpairs()
@*/
PetscErrorCode EPSSetTarget(EPS eps,PetscScalar target)
{
    PetscErrorCode ierr;

    PetscFunctionBegin;
    PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
    PetscValidLogicalCollectiveScalar(eps,target,2);
    eps->target = target;
    if (!eps->st) {
        ierr = EPSGetST(eps,&eps->st);
        CHKERRQ(ierr);
    }
    ierr = STSetDefaultShift(eps->st,target);
    CHKERRQ(ierr);
    PetscFunctionReturn(0);
}
예제 #3
0
/*@C
   EPSAppendOptionsPrefix - Appends to the prefix used for searching for all
   EPS options in the database.

   Logically Collective on EPS

   Input Parameters:
+  eps - the eigensolver context
-  prefix - the prefix string to prepend to all EPS option requests

   Notes:
   A hyphen (-) must NOT be given at the beginning of the prefix name.
   The first character of all runtime options is AUTOMATICALLY the hyphen.

   Level: advanced

.seealso: EPSSetOptionsPrefix(), EPSGetOptionsPrefix()
@*/
PetscErrorCode EPSAppendOptionsPrefix(EPS eps,const char *prefix)
{
  PetscErrorCode ierr;

  PetscFunctionBegin;
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
  if (!eps->st) { ierr = EPSGetST(eps,&eps->st);CHKERRQ(ierr); }
  ierr = STAppendOptionsPrefix(eps->st,prefix);CHKERRQ(ierr);
  if (!eps->V) { ierr = EPSGetBV(eps,&eps->V);CHKERRQ(ierr); }
  ierr = BVSetOptionsPrefix(eps->V,prefix);CHKERRQ(ierr);
  if (!eps->ds) { ierr = EPSGetDS(eps,&eps->ds);CHKERRQ(ierr); }
  ierr = DSSetOptionsPrefix(eps->ds,prefix);CHKERRQ(ierr);
  if (!eps->rg) { ierr = EPSGetRG(eps,&eps->rg);CHKERRQ(ierr); }
  ierr = RGSetOptionsPrefix(eps->rg,prefix);CHKERRQ(ierr);
  ierr = PetscObjectAppendOptionsPrefix((PetscObject)eps,prefix);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
예제 #4
0
static PetscErrorCode EPSMonitor_Linear(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *ctx)
{
  PetscInt       i;
  PEP            pep = (PEP)ctx;
  ST             st;
  PetscErrorCode ierr;

  PetscFunctionBegin;
  for (i=0;i<PetscMin(nest,pep->ncv);i++) {
    pep->eigr[i] = eigr[i];
    pep->eigi[i] = eigi[i];
    pep->errest[i] = errest[i];
  }
  ierr = EPSGetST(eps,&st);CHKERRQ(ierr);
  ierr = STBackTransform(st,nest,pep->eigr,pep->eigi);CHKERRQ(ierr);
  ierr = PEPMonitor(pep,its,nconv,pep->eigr,pep->eigi,pep->errest,nest);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
예제 #5
0
static PetscErrorCode NEPSLPGetEPS_SLP(NEP nep,EPS *eps)
{
  PetscErrorCode ierr;
  NEP_SLP        *ctx = (NEP_SLP*)nep->data;
  ST             st;

  PetscFunctionBegin;
  if (!ctx->eps) {
    ierr = EPSCreate(PetscObjectComm((PetscObject)nep),&ctx->eps);CHKERRQ(ierr);
    ierr = EPSSetOptionsPrefix(ctx->eps,((PetscObject)nep)->prefix);CHKERRQ(ierr);
    ierr = EPSAppendOptionsPrefix(ctx->eps,"nep_");CHKERRQ(ierr);
    ierr = EPSGetST(ctx->eps,&st);CHKERRQ(ierr);
    ierr = STSetOptionsPrefix(st,((PetscObject)ctx->eps)->prefix);CHKERRQ(ierr);
    ierr = PetscObjectIncrementTabLevel((PetscObject)ctx->eps,(PetscObject)nep,1);CHKERRQ(ierr);
    ierr = PetscLogObjectParent((PetscObject)nep,(PetscObject)ctx->eps);CHKERRQ(ierr);
  }
  *eps = ctx->eps;
  PetscFunctionReturn(0);
}
예제 #6
0
static PetscErrorCode PEPLinearGetEPS_Linear(PEP pep,EPS *eps)
{
  PetscErrorCode ierr;
  PEP_LINEAR     *ctx = (PEP_LINEAR*)pep->data;
  ST             st;

  PetscFunctionBegin;
  if (!ctx->eps) {
    ierr = EPSCreate(PetscObjectComm((PetscObject)pep),&ctx->eps);CHKERRQ(ierr);
    ierr = EPSSetOptionsPrefix(ctx->eps,((PetscObject)pep)->prefix);CHKERRQ(ierr);
    ierr = EPSAppendOptionsPrefix(ctx->eps,"pep_");CHKERRQ(ierr);
    ierr = EPSGetST(ctx->eps,&st);CHKERRQ(ierr);
    ierr = STSetOptionsPrefix(st,((PetscObject)ctx->eps)->prefix);CHKERRQ(ierr);
    ierr = PetscObjectIncrementTabLevel((PetscObject)ctx->eps,(PetscObject)pep,1);CHKERRQ(ierr);
    ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->eps);CHKERRQ(ierr);
    ierr = EPSMonitorSet(ctx->eps,EPSMonitor_Linear,pep,NULL);CHKERRQ(ierr);
  }
  *eps = ctx->eps;
  PetscFunctionReturn(0);
}
예제 #7
0
PetscErrorCode NEPSetUp_SLP(NEP nep)
{
  PetscErrorCode ierr;
  NEP_SLP        *ctx = (NEP_SLP*)nep->data;
  ST             st;
  PetscBool      istrivial;

  PetscFunctionBegin;
  if (nep->ncv) { /* ncv set */
    if (nep->ncv<nep->nev) SETERRQ(PetscObjectComm((PetscObject)nep),1,"The value of ncv must be at least nev");
  } else if (nep->mpd) { /* mpd set */
    nep->ncv = PetscMin(nep->n,nep->nev+nep->mpd);
  } else { /* neither set: defaults depend on nev being small or large */
    if (nep->nev<500) nep->ncv = PetscMin(nep->n,PetscMax(2*nep->nev,nep->nev+15));
    else {
      nep->mpd = 500;
      nep->ncv = PetscMin(nep->n,nep->nev+nep->mpd);
    }
  }
  if (!nep->mpd) nep->mpd = nep->ncv;
  if (nep->ncv>nep->nev+nep->mpd) SETERRQ(PetscObjectComm((PetscObject)nep),1,"The value of ncv must not be larger than nev+mpd");
  if (nep->nev>1) { ierr = PetscInfo(nep,"Warning: requested more than one eigenpair but SLP can only compute one\n");CHKERRQ(ierr); }
  if (!nep->max_it) nep->max_it = PetscMax(5000,2*nep->n/nep->ncv);
  if (!nep->max_funcs) nep->max_funcs = nep->max_it;

  ierr = RGIsTrivial(nep->rg,&istrivial);CHKERRQ(ierr);
  if (!istrivial) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"This solver does not support region filtering");

  if (!ctx->eps) { ierr = NEPSLPGetEPS(nep,&ctx->eps);CHKERRQ(ierr); }
  ierr = EPSSetWhichEigenpairs(ctx->eps,EPS_TARGET_MAGNITUDE);CHKERRQ(ierr);
  ierr = EPSSetTarget(ctx->eps,0.0);CHKERRQ(ierr);
  ierr = EPSGetST(ctx->eps,&st);CHKERRQ(ierr);
  ierr = STSetType(st,STSINVERT);CHKERRQ(ierr);
  ierr = EPSSetDimensions(ctx->eps,1,nep->ncv?nep->ncv:PETSC_DEFAULT,nep->mpd?nep->mpd:PETSC_DEFAULT);CHKERRQ(ierr);
  ierr = EPSSetTolerances(ctx->eps,nep->rtol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL/10.0:nep->rtol/10.0,nep->max_it?nep->max_it:PETSC_DEFAULT);CHKERRQ(ierr);

  ierr = NEPAllocateSolution(nep,0);CHKERRQ(ierr);
  ierr = NEPSetWorkVecs(nep,1);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
예제 #8
0
int main(int argc,char **argv)
{
  Mat            A;           /* problem matrix */
  EPS            eps;         /* eigenproblem solver context */
  ST             st;
  PetscReal      tol=PetscMax(1000*PETSC_MACHINE_EPSILON,1e-9);
  PetscScalar    value[3];
  PetscInt       n=30,i,Istart,Iend,col[3];
  PetscBool      FirstBlock=PETSC_FALSE,LastBlock=PETSC_FALSE,flg;
  PetscErrorCode ierr;

  SlepcInitialize(&argc,&argv,(char*)0,help);

  ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"\n1-D Laplacian Eigenproblem, n=%D\n\n",n);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Compute the operator matrix that defines the eigensystem, Ax=kx
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr);
  ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr);
  ierr = MatSetFromOptions(A);CHKERRQ(ierr);
  ierr = MatSetUp(A);CHKERRQ(ierr);

  ierr = MatGetOwnershipRange(A,&Istart,&Iend);CHKERRQ(ierr);
  if (Istart==0) FirstBlock=PETSC_TRUE;
  if (Iend==n) LastBlock=PETSC_TRUE;
  value[0]=-1.0; value[1]=2.0; value[2]=-1.0;
  for (i=(FirstBlock? Istart+1: Istart); i<(LastBlock? Iend-1: Iend); i++) {
    col[0]=i-1; col[1]=i; col[2]=i+1;
    ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr);
  }
  if (LastBlock) {
    i=n-1; col[0]=n-2; col[1]=n-1;
    ierr = MatSetValues(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr);
  }
  if (FirstBlock) {
    i=0; col[0]=0; col[1]=1; value[0]=2.0; value[1]=-1.0;
    ierr = MatSetValues(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr);
  }

  ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                        Create the eigensolver
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr);
  ierr = EPSSetOperators(eps,A,NULL);CHKERRQ(ierr);
  ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr);
  ierr = EPSSetTolerances(eps,tol,PETSC_DEFAULT);CHKERRQ(ierr);
  ierr = EPSSetFromOptions(eps);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                    Solve for largest eigenvalues
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = EPSSetWhichEigenpairs(eps,EPS_LARGEST_REAL);CHKERRQ(ierr);
  ierr = EPSSolve(eps);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD," - - - Largest eigenvalues - - -\n");CHKERRQ(ierr);
  ierr = EPSPrintSolution(eps,NULL);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                    Solve for smallest eigenvalues
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = EPSSetWhichEigenpairs(eps,EPS_SMALLEST_REAL);CHKERRQ(ierr);
  ierr = EPSSolve(eps);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD," - - - Smallest eigenvalues - - -\n");CHKERRQ(ierr);
  ierr = EPSPrintSolution(eps,NULL);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                    Solve for interior eigenvalues (target=2.1)
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE);CHKERRQ(ierr);
  ierr = EPSSetTarget(eps,2.1);CHKERRQ(ierr);
  ierr = PetscObjectTypeCompare((PetscObject)eps,EPSLANCZOS,&flg);CHKERRQ(ierr);
  if (flg) {
    ierr = EPSGetST(eps,&st);CHKERRQ(ierr);
    ierr = STSetType(st,STSINVERT);CHKERRQ(ierr);
  } else {
    ierr = PetscObjectTypeCompare((PetscObject)eps,EPSKRYLOVSCHUR,&flg);CHKERRQ(ierr);
    if (!flg) {
      ierr = PetscObjectTypeCompare((PetscObject)eps,EPSARNOLDI,&flg);CHKERRQ(ierr);
    }
    if (flg) {
      ierr = EPSSetExtraction(eps,EPS_HARMONIC);CHKERRQ(ierr);
    }
  }
  ierr = EPSSolve(eps);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD," - - - Interior eigenvalues - - -\n");CHKERRQ(ierr);
  ierr = EPSPrintSolution(eps,NULL);CHKERRQ(ierr);

  ierr = EPSDestroy(&eps);CHKERRQ(ierr);
  ierr = MatDestroy(&A);CHKERRQ(ierr);
  ierr = SlepcFinalize();
  return 0;
}
예제 #9
0
void TrustRegionSolver3::calcSmallestEigVal(double &oEigVal, FloatArray &oEigVec, PetscSparseMtrx &K) {
    PetscErrorCode ierr;
    ST st;

    double eig_rtol = 1.0e-3;
    int max_iter = 10000;
    int nroot = 1;

    if ( !epsInit ) {
        /*
         * Create eigensolver context
         */
#ifdef __PARALLEL_MODE
        MPI_Comm comm = engngModel->giveParallelComm();
#else
        MPI_Comm comm = PETSC_COMM_SELF;
#endif
        ierr = EPSCreate(comm, & eps);
        checkPetscError(ierr);
        epsInit = true;
    }

    ierr = EPSSetOperators( eps, * K.giveMtrx(), NULL );
    checkPetscError(ierr);

    ierr = EPSSetProblemType(eps, EPS_NHEP);
    checkPetscError(ierr);

    ierr = EPSGetST(eps, & st);
    checkPetscError(ierr);

//        ierr = STSetType(st, STCAYLEY);
//        ierr = STSetType(st, STSINVERT);
        ierr = STSetType(st, STSHIFT);
        checkPetscError(ierr);

    ierr = STSetMatStructure(st, SAME_NONZERO_PATTERN);
    checkPetscError(ierr);

    ierr = EPSSetTolerances(eps, ( PetscReal ) eig_rtol, max_iter);
    checkPetscError(ierr);

    ierr = EPSSetDimensions(eps, ( PetscInt ) nroot, PETSC_DECIDE, PETSC_DECIDE);
    checkPetscError(ierr);

    ierr = EPSSetWhichEigenpairs(eps, EPS_SMALLEST_REAL);
    checkPetscError(ierr);


    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     *                   Solve the eigensystem
     *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    EPSConvergedReason eig_reason;
    int eig_nconv, eig_nite;

    ierr = EPSSolve(eps);
    checkPetscError(ierr);

    ierr = EPSGetConvergedReason(eps, & eig_reason);
    checkPetscError(ierr);

    ierr = EPSGetIterationNumber(eps, & eig_nite);
    checkPetscError(ierr);
//    printf("SLEPcSolver::solve EPSConvergedReason: %d, number of iterations: %d\n", eig_reason, eig_nite);

    ierr = EPSGetConverged(eps, & eig_nconv);
    checkPetscError(ierr);

    double smallest_eig_val = 1.0e20;

    if ( eig_nconv > 0 ) {
//        printf("SLEPcSolver :: solveYourselfAt: Convergence reached for RTOL=%20.15f\n", eig_rtol);

    	FloatArray eig_vals(nroot);
        PetscScalar kr;
        Vec Vr;

        K.createVecGlobal(& Vr);


            FloatArray Vr_loc;

        for ( int i = 0; i < eig_nconv && i < nroot; i++ ) {
        	// PetscErrorCode EPSGetEigenpair(EPS eps,PetscInt i,PetscScalar *eigr,PetscScalar *eigi,Vec Vr,Vec Vi)
            ierr = EPSGetEigenpair(eps, i, & kr, PETSC_NULL, Vr, PETSC_NULL);
            checkPetscError(ierr);

            //Store the eigenvalue
            eig_vals(i) = kr;

            if(kr < smallest_eig_val) {
            	smallest_eig_val = kr;

            	K.scatterG2L(Vr, Vr_loc);
            	oEigVec = Vr_loc;
            }

        }

        ierr = VecDestroy(& Vr);
        checkPetscError(ierr);

    } else {
//        OOFEM_ERROR("No converged eigenpairs.\n");
    	printf("Warning: No converged eigenpairs.\n");
    	smallest_eig_val = 1.0;
    }

    oEigVal = smallest_eig_val;
}
예제 #10
0
NM_Status
SLEPcSolver :: solve(SparseMtrx &a, SparseMtrx &b, FloatArray &_eigv, FloatMatrix &_r, double rtol, int nroot)
{
    FILE *outStream;
    PetscErrorCode ierr;
    int size;
    ST st;

    outStream = domain->giveEngngModel()->giveOutputStream();

    // first check whether Lhs is defined

    if ( a->giveNumberOfRows() != a->giveNumberOfColumns() ||
        b->giveNumberOfRows() != b->giveNumberOfRows() ||
        a->giveNumberOfColumns() != b->giveNumberOfColumns() ) {
        OOFEM_ERROR("matrices size mismatch");
    }

    A = dynamic_cast< PetscSparseMtrx * >(&a);
    B = dynamic_cast< PetscSparseMtrx * >(&b);

    if ( !A || !B ) {
        OOFEM_ERROR("PetscSparseMtrx Expected");
    }

    size = engngModel->giveParallelContext( A->giveDomainIndex() )->giveNumberOfNaturalEqs(); // A->giveLeqs();

    _r.resize(size, nroot);
    _eigv.resize(nroot);


    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     *             Create the eigensolver and set various options
     *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    int nconv, nite;
    EPSConvergedReason reason;

#ifdef TIME_REPORT
    Timer timer;
    timer.startTimer();
#endif

    if ( !epsInit ) {
        /*
         * Create eigensolver context
         */
#ifdef __PARALLEL_MODE
        MPI_Comm comm = engngModel->giveParallelComm();
#else
        MPI_Comm comm = PETSC_COMM_SELF;
#endif
        ierr = EPSCreate(comm, & eps);
        CHKERRQ(ierr);
        epsInit = true;
    }

    /*
     * Set operators. In this case, it is a generalized eigenvalue problem
     */

    ierr = EPSSetOperators( eps, * A->giveMtrx(), * B->giveMtrx() );
    CHKERRQ(ierr);
    ierr = EPSSetProblemType(eps, EPS_GHEP);
    CHKERRQ(ierr);
    ierr = EPSGetST(eps, & st);
    CHKERRQ(ierr);
    ierr = STSetType(st, STSINVERT);
    CHKERRQ(ierr);
    ierr = STSetMatStructure(st, SAME_NONZERO_PATTERN);
    CHKERRQ(ierr);
    ierr = EPSSetTolerances(eps, ( PetscReal ) rtol, PETSC_DECIDE);
    CHKERRQ(ierr);
    ierr = EPSSetDimensions(eps, ( PetscInt ) nroot, PETSC_DECIDE, PETSC_DECIDE);
    CHKERRQ(ierr);
    ierr = EPSSetWhichEigenpairs(eps, EPS_SMALLEST_MAGNITUDE);
    CHKERRQ(ierr);

    /*
     * Set solver parameters at runtime
     */

    ierr = EPSSetFromOptions(eps);
    CHKERRQ(ierr);

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     *                   Solve the eigensystem
     *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    ierr = EPSSolve(eps);
    CHKERRQ(ierr);

    ierr = EPSGetConvergedReason(eps, & reason);
    CHKERRQ(ierr);
    ierr = EPSGetIterationNumber(eps, & nite);
    CHKERRQ(ierr);
    OOFEM_LOG_INFO("SLEPcSolver::solve EPSConvergedReason: %d, number of iterations: %d\n", reason, nite);

    ierr = EPSGetConverged(eps, & nconv);
    CHKERRQ(ierr);

    if ( nconv > 0 ) {
        fprintf(outStream, "SLEPcSolver :: solveYourselfAt: Convergence reached for RTOL=%20.15f", rtol);
        PetscScalar kr;
        Vec Vr;

        ierr = MatGetVecs(* B->giveMtrx(), PETSC_NULL, & Vr);
        CHKERRQ(ierr);

        FloatArray Vr_loc;

        for ( int i = 0; i < nconv && i < nroot; i++ ) {
            ierr = EPSGetEigenpair(eps, nconv - i - 1, & kr, PETSC_NULL, Vr, PETSC_NULL);
            CHKERRQ(ierr);

            //Store the eigenvalue
            _eigv->at(i + 1) = kr;

            //Store the eigenvector
            A->scatterG2L(Vr, Vr_loc);
            for ( int j = 0; j < size; j++ ) {
                _r->at(j + 1, i + 1) = Vr_loc.at(j + 1);
            }
        }

        ierr = VecDestroy(Vr);
        CHKERRQ(ierr);
    } else {
        OOFEM_ERROR("No converged eigenpairs");
    }

#ifdef TIME_REPORT
    timer.stopTimer();
    OOFEM_LOG_INFO( "SLEPcSolver info: user time consumed by solution: %.2fs\n", timer.getUtime() );
#endif

    return NM_Success;
}
예제 #11
0
/*@C
   EPSView - Prints the EPS data structure.

   Collective on EPS

   Input Parameters:
+  eps - the eigenproblem solver context
-  viewer - optional visualization context

   Options Database Key:
.  -eps_view -  Calls EPSView() at end of EPSSolve()

   Note:
   The available visualization contexts include
+     PETSC_VIEWER_STDOUT_SELF - standard output (default)
-     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
         output where only the first processor opens
         the file.  All other processors send their
         data to the first processor to print.

   The user can open an alternative visualization context with
   PetscViewerASCIIOpen() - output to a specified file.

   Level: beginner

.seealso: STView(), PetscViewerASCIIOpen()
@*/
PetscErrorCode EPSView(EPS eps,PetscViewer viewer)
{
    PetscErrorCode ierr;
    const char     *type,*extr,*bal;
    char           str[50];
    PetscBool      isascii,ispower,isexternal,istrivial;

    PetscFunctionBegin;
    PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
    if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)eps));
    PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
    PetscCheckSameComm(eps,1,viewer,2);

#if defined(PETSC_USE_COMPLEX)
#define HERM "hermitian"
#else
#define HERM "symmetric"
#endif
    ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    CHKERRQ(ierr);
    if (isascii) {
        ierr = PetscObjectPrintClassNamePrefixType((PetscObject)eps,viewer);
        CHKERRQ(ierr);
        if (eps->ops->view) {
            ierr = PetscViewerASCIIPushTab(viewer);
            CHKERRQ(ierr);
            ierr = (*eps->ops->view)(eps,viewer);
            CHKERRQ(ierr);
            ierr = PetscViewerASCIIPopTab(viewer);
            CHKERRQ(ierr);
        }
        if (eps->problem_type) {
            switch (eps->problem_type) {
            case EPS_HEP:
                type = HERM " eigenvalue problem";
                break;
            case EPS_GHEP:
                type = "generalized " HERM " eigenvalue problem";
                break;
            case EPS_NHEP:
                type = "non-" HERM " eigenvalue problem";
                break;
            case EPS_GNHEP:
                type = "generalized non-" HERM " eigenvalue problem";
                break;
            case EPS_PGNHEP:
                type = "generalized non-" HERM " eigenvalue problem with " HERM " positive definite B";
                break;
            case EPS_GHIEP:
                type = "generalized " HERM "-indefinite eigenvalue problem";
                break;
            default:
                SETERRQ(PetscObjectComm((PetscObject)eps),1,"Wrong value of eps->problem_type");
            }
        } else type = "not yet set";
        ierr = PetscViewerASCIIPrintf(viewer,"  problem type: %s\n",type);
        CHKERRQ(ierr);
        if (eps->extraction) {
            switch (eps->extraction) {
            case EPS_RITZ:
                extr = "Rayleigh-Ritz";
                break;
            case EPS_HARMONIC:
                extr = "harmonic Ritz";
                break;
            case EPS_HARMONIC_RELATIVE:
                extr = "relative harmonic Ritz";
                break;
            case EPS_HARMONIC_RIGHT:
                extr = "right harmonic Ritz";
                break;
            case EPS_HARMONIC_LARGEST:
                extr = "largest harmonic Ritz";
                break;
            case EPS_REFINED:
                extr = "refined Ritz";
                break;
            case EPS_REFINED_HARMONIC:
                extr = "refined harmonic Ritz";
                break;
            default:
                SETERRQ(PetscObjectComm((PetscObject)eps),1,"Wrong value of eps->extraction");
            }
            ierr = PetscViewerASCIIPrintf(viewer,"  extraction type: %s\n",extr);
            CHKERRQ(ierr);
        }
        if (!eps->ishermitian && eps->balance!=EPS_BALANCE_NONE) {
            switch (eps->balance) {
            case EPS_BALANCE_ONESIDE:
                bal = "one-sided Krylov";
                break;
            case EPS_BALANCE_TWOSIDE:
                bal = "two-sided Krylov";
                break;
            case EPS_BALANCE_USER:
                bal = "user-defined matrix";
                break;
            default:
                SETERRQ(PetscObjectComm((PetscObject)eps),1,"Wrong value of eps->balance");
            }
            ierr = PetscViewerASCIIPrintf(viewer,"  balancing enabled: %s",bal);
            CHKERRQ(ierr);
            if (eps->balance==EPS_BALANCE_ONESIDE || eps->balance==EPS_BALANCE_TWOSIDE) {
                ierr = PetscViewerASCIIPrintf(viewer,", with its=%D",eps->balance_its);
                CHKERRQ(ierr);
            }
            if (eps->balance==EPS_BALANCE_TWOSIDE && eps->balance_cutoff!=0.0) {
                ierr = PetscViewerASCIIPrintf(viewer," and cutoff=%g",(double)eps->balance_cutoff);
                CHKERRQ(ierr);
            }
            ierr = PetscViewerASCIIPrintf(viewer,"\n");
            CHKERRQ(ierr);
        }
        ierr = PetscViewerASCIIPrintf(viewer,"  selected portion of the spectrum: ");
        CHKERRQ(ierr);
        ierr = SlepcSNPrintfScalar(str,50,eps->target,PETSC_FALSE);
        CHKERRQ(ierr);
        if (!eps->which) {
            ierr = PetscViewerASCIIPrintf(viewer,"not yet set\n");
            CHKERRQ(ierr);
        } else switch (eps->which) {
            case EPS_WHICH_USER:
                ierr = PetscViewerASCIIPrintf(viewer,"user defined\n");
                CHKERRQ(ierr);
                break;
            case EPS_TARGET_MAGNITUDE:
                ierr = PetscViewerASCIIPrintf(viewer,"closest to target: %s (in magnitude)\n",str);
                CHKERRQ(ierr);
                break;
            case EPS_TARGET_REAL:
                ierr = PetscViewerASCIIPrintf(viewer,"closest to target: %s (along the real axis)\n",str);
                CHKERRQ(ierr);
                break;
            case EPS_TARGET_IMAGINARY:
                ierr = PetscViewerASCIIPrintf(viewer,"closest to target: %s (along the imaginary axis)\n",str);
                CHKERRQ(ierr);
                break;
            case EPS_LARGEST_MAGNITUDE:
                ierr = PetscViewerASCIIPrintf(viewer,"largest eigenvalues in magnitude\n");
                CHKERRQ(ierr);
                break;
            case EPS_SMALLEST_MAGNITUDE:
                ierr = PetscViewerASCIIPrintf(viewer,"smallest eigenvalues in magnitude\n");
                CHKERRQ(ierr);
                break;
            case EPS_LARGEST_REAL:
                ierr = PetscViewerASCIIPrintf(viewer,"largest real parts\n");
                CHKERRQ(ierr);
                break;
            case EPS_SMALLEST_REAL:
                ierr = PetscViewerASCIIPrintf(viewer,"smallest real parts\n");
                CHKERRQ(ierr);
                break;
            case EPS_LARGEST_IMAGINARY:
                ierr = PetscViewerASCIIPrintf(viewer,"largest imaginary parts\n");
                CHKERRQ(ierr);
                break;
            case EPS_SMALLEST_IMAGINARY:
                ierr = PetscViewerASCIIPrintf(viewer,"smallest imaginary parts\n");
                CHKERRQ(ierr);
                break;
            case EPS_ALL:
                ierr = PetscViewerASCIIPrintf(viewer,"all eigenvalues in interval [%g,%g]\n",(double)eps->inta,(double)eps->intb);
                CHKERRQ(ierr);
                break;
            default:
                SETERRQ(PetscObjectComm((PetscObject)eps),1,"Wrong value of eps->which");
            }
        if (eps->trueres) {
            ierr = PetscViewerASCIIPrintf(viewer,"  computing true residuals explicitly\n");
            CHKERRQ(ierr);
        }
        if (eps->trackall) {
            ierr = PetscViewerASCIIPrintf(viewer,"  computing all residuals (for tracking convergence)\n");
            CHKERRQ(ierr);
        }
        ierr = PetscViewerASCIIPrintf(viewer,"  number of eigenvalues (nev): %D\n",eps->nev);
        CHKERRQ(ierr);
        ierr = PetscViewerASCIIPrintf(viewer,"  number of column vectors (ncv): %D\n",eps->ncv);
        CHKERRQ(ierr);
        ierr = PetscViewerASCIIPrintf(viewer,"  maximum dimension of projected problem (mpd): %D\n",eps->mpd);
        CHKERRQ(ierr);
        ierr = PetscViewerASCIIPrintf(viewer,"  maximum number of iterations: %D\n",eps->max_it);
        CHKERRQ(ierr);
        ierr = PetscViewerASCIIPrintf(viewer,"  tolerance: %g\n",(double)eps->tol);
        CHKERRQ(ierr);
        ierr = PetscViewerASCIIPrintf(viewer,"  convergence test: ");
        CHKERRQ(ierr);
        switch (eps->conv) {
        case EPS_CONV_ABS:
            ierr = PetscViewerASCIIPrintf(viewer,"absolute\n");
            CHKERRQ(ierr);
            break;
        case EPS_CONV_EIG:
            ierr = PetscViewerASCIIPrintf(viewer,"relative to the eigenvalue\n");
            CHKERRQ(ierr);
            break;
        case EPS_CONV_NORM:
            ierr = PetscViewerASCIIPrintf(viewer,"relative to the eigenvalue and matrix norms\n");
            CHKERRQ(ierr);
            ierr = PetscViewerASCIIPrintf(viewer,"  computed matrix norms: norm(A)=%g",(double)eps->nrma);
            CHKERRQ(ierr);
            if (eps->isgeneralized) {
                ierr = PetscViewerASCIIPrintf(viewer,", norm(B)=%g",(double)eps->nrmb);
                CHKERRQ(ierr);
            }
            ierr = PetscViewerASCIIPrintf(viewer,"\n");
            CHKERRQ(ierr);
            break;
        case EPS_CONV_USER:
            ierr = PetscViewerASCIIPrintf(viewer,"user-defined\n");
            CHKERRQ(ierr);
            break;
        }
        if (eps->nini) {
            ierr = PetscViewerASCIIPrintf(viewer,"  dimension of user-provided initial space: %D\n",PetscAbs(eps->nini));
            CHKERRQ(ierr);
        }
        if (eps->nds) {
            ierr = PetscViewerASCIIPrintf(viewer,"  dimension of user-provided deflation space: %D\n",PetscAbs(eps->nds));
            CHKERRQ(ierr);
        }
    } else {
        if (eps->ops->view) {
            ierr = (*eps->ops->view)(eps,viewer);
            CHKERRQ(ierr);
        }
    }
    ierr = PetscObjectTypeCompareAny((PetscObject)eps,&isexternal,EPSARPACK,EPSBLZPACK,EPSTRLAN,EPSBLOPEX,EPSPRIMME,"");
    CHKERRQ(ierr);
    if (!isexternal) {
        ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
        CHKERRQ(ierr);
        if (!eps->V) {
            ierr = EPSGetBV(eps,&eps->V);
            CHKERRQ(ierr);
        }
        ierr = BVView(eps->V,viewer);
        CHKERRQ(ierr);
        if (!eps->rg) {
            ierr = EPSGetRG(eps,&eps->rg);
            CHKERRQ(ierr);
        }
        ierr = RGIsTrivial(eps->rg,&istrivial);
        CHKERRQ(ierr);
        if (!istrivial) {
            ierr = RGView(eps->rg,viewer);
            CHKERRQ(ierr);
        }
        ierr = PetscObjectTypeCompare((PetscObject)eps,EPSPOWER,&ispower);
        CHKERRQ(ierr);
        if (!ispower) {
            if (!eps->ds) {
                ierr = EPSGetDS(eps,&eps->ds);
                CHKERRQ(ierr);
            }
            ierr = DSView(eps->ds,viewer);
            CHKERRQ(ierr);
        }
        ierr = PetscViewerPopFormat(viewer);
        CHKERRQ(ierr);
    }
    if (!eps->st) {
        ierr = EPSGetST(eps,&eps->st);
        CHKERRQ(ierr);
    }
    ierr = STView(eps->st,viewer);
    CHKERRQ(ierr);
    PetscFunctionReturn(0);
}