Subversion Repositories slepc-dev

Rev

Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1937 Rev 1940
Line 63... Line 63...
  else eps->ncv = eps->nev;
  else eps->ncv = eps->nev;
  if (eps->mpd) PetscInfo(eps,"Warning: parameter mpd ignored\n");
  if (eps->mpd) PetscInfo(eps,"Warning: parameter mpd ignored\n");
  if (!eps->max_it) eps->max_it = PetscMax(2000,100*eps->n);
  if (!eps->max_it) eps->max_it = PetscMax(2000,100*eps->n);
  if (eps->which!=EPS_LARGEST_MAGNITUDE)
  if (eps->which!=EPS_LARGEST_MAGNITUDE)
    SETERRQ(1,"Wrong value of eps->which");
    SETERRQ(1,"Wrong value of eps->which");
  if (power->shift_type != EPSPOWER_SHIFT_CONSTANT) {
  if (power->shift_type != EPS_POWER_SHIFT_CONSTANT) {
    ierr = PetscTypeCompare((PetscObject)eps->OP,STSINV,&flg);CHKERRQ(ierr);
    ierr = PetscTypeCompare((PetscObject)eps->OP,STSINV,&flg);CHKERRQ(ierr);
    if (!flg)
    if (!flg)
      SETERRQ(PETSC_ERR_SUP,"Variable shifts only allowed in shift-and-invert ST");
      SETERRQ(PETSC_ERR_SUP,"Variable shifts only allowed in shift-and-invert ST");
    ierr = STGetMatMode(eps->OP,&mode);CHKERRQ(ierr);
    ierr = STGetMatMode(eps->OP,&mode);CHKERRQ(ierr);
    if (mode == STMATMODE_INPLACE)
    if (mode == ST_MATMODE_INPLACE)
      SETERRQ(PETSC_ERR_SUP,"ST matrix mode inplace does not work with variable shifts");
      SETERRQ(PETSC_ERR_SUP,"ST matrix mode inplace does not work with variable shifts");
  }
  }
  if (eps->extraction) {
  if (eps->extraction) {
     ierr = PetscInfo(eps,"Warning: extraction type ignored\n");CHKERRQ(ierr);
     ierr = PetscInfo(eps,"Warning: extraction type ignored\n");CHKERRQ(ierr);
  }
  }
  if (eps->balance!=EPSBALANCE_NONE)
  if (eps->balance!=EPS_BALANCE_NONE)
    SETERRQ(PETSC_ERR_SUP,"Balancing not supported in this solver");
    SETERRQ(PETSC_ERR_SUP,"Balancing not supported in this solver");
  ierr = EPSAllocateSolution(eps);CHKERRQ(ierr);
  ierr = EPSAllocateSolution(eps);CHKERRQ(ierr);
  if (eps->solverclass == EPS_TWO_SIDE) {
  if (eps->solverclass == EPS_TWO_SIDE) {
    ierr = EPSDefaultGetWork(eps,3);CHKERRQ(ierr);
    ierr = EPSDefaultGetWork(eps,3);CHKERRQ(ierr);
  } else {
  } else {
Line 104... Line 104...
  v = eps->V[0];
  v = eps->V[0];
  y = eps->work[1];
  y = eps->work[1];
  e = eps->work[0];
  e = eps->work[0];
 
 
  /* prepare for selective orthogonalization of converged vectors */
  /* prepare for selective orthogonalization of converged vectors */
  if (power->shift_type != EPSPOWER_SHIFT_CONSTANT && eps->nev>1) {
  if (power->shift_type != EPS_POWER_SHIFT_CONSTANT && eps->nev>1) {
    ierr = STGetOperators(eps->OP,&A,PETSC_NULL);CHKERRQ(ierr);
    ierr = STGetOperators(eps->OP,&A,PETSC_NULL);CHKERRQ(ierr);
    ierr = MatHasOperation(A,MATOP_NORM,&hasnorm);CHKERRQ(ierr);
    ierr = MatHasOperation(A,MATOP_NORM,&hasnorm);CHKERRQ(ierr);
    if (hasnorm) {
    if (hasnorm) {
      ierr = MatNorm(A,NORM_INFINITY,&anorm);CHKERRQ(ierr);
      ierr = MatNorm(A,NORM_INFINITY,&anorm);CHKERRQ(ierr);
      ierr = PetscMalloc(eps->nev*sizeof(PetscTruth),&select);CHKERRQ(ierr);
      ierr = PetscMalloc(eps->nev*sizeof(PetscTruth),&select);CHKERRQ(ierr);
Line 126... Line 126...
    ierr = STApply(eps->OP,v,y);CHKERRQ(ierr);
    ierr = STApply(eps->OP,v,y);CHKERRQ(ierr);
 
 
    /* theta = (v,y)_B */
    /* theta = (v,y)_B */
    ierr = IPInnerProduct(eps->ip,v,y,&theta);CHKERRQ(ierr);
    ierr = IPInnerProduct(eps->ip,v,y,&theta);CHKERRQ(ierr);
 
 
    if (power->shift_type == EPSPOWER_SHIFT_CONSTANT) { /* direct & inverse iteration */
    if (power->shift_type == EPS_POWER_SHIFT_CONSTANT) { /* direct & inverse iteration */
 
 
      /* approximate eigenvalue is the Rayleigh quotient */
      /* approximate eigenvalue is the Rayleigh quotient */
      eps->eigr[eps->nconv] = theta;
      eps->eigr[eps->nconv] = theta;
 
 
      /* compute relative error as ||y-theta v||_2/|theta| */
      /* compute relative error as ||y-theta v||_2/|theta| */
Line 156... Line 156...
      if (relerr<eps->tol) {
      if (relerr<eps->tol) {
        rho = sigma; /* if converged, restore original shift */
        rho = sigma; /* if converged, restore original shift */
        ierr = STSetShift(eps->OP,rho);CHKERRQ(ierr);
        ierr = STSetShift(eps->OP,rho);CHKERRQ(ierr);
      } else {
      } else {
        rho = rho + theta/(delta*delta);  /* Rayleigh quotient R(v) */
        rho = rho + theta/(delta*delta);  /* Rayleigh quotient R(v) */
        if (power->shift_type == EPSPOWER_SHIFT_WILKINSON) {
        if (power->shift_type == EPS_POWER_SHIFT_WILKINSON) {
#if defined(SLEPC_MISSING_LAPACK_LAEV2)
#if defined(SLEPC_MISSING_LAPACK_LAEV2)
          SETERRQ(PETSC_ERR_SUP,"LAEV2 - Lapack routine is unavailable.");
          SETERRQ(PETSC_ERR_SUP,"LAEV2 - Lapack routine is unavailable.");
#else
#else
          /* beta1 is the norm of the residual associated to R(v) */
          /* beta1 is the norm of the residual associated to R(v) */
          ierr = VecAXPY(v,-theta/(delta*delta),y);CHKERRQ(ierr);
          ierr = VecAXPY(v,-theta/(delta*delta),y);CHKERRQ(ierr);
Line 264... Line 264...
    ierr = STApplyTranspose(eps->OP,w,z);CHKERRQ(ierr);
    ierr = STApplyTranspose(eps->OP,w,z);CHKERRQ(ierr);
 
 
    /* theta = (v,z)_B */
    /* theta = (v,z)_B */
    ierr = IPInnerProduct(eps->ip,v,z,&theta);CHKERRQ(ierr);
    ierr = IPInnerProduct(eps->ip,v,z,&theta);CHKERRQ(ierr);
 
 
    if (power->shift_type == EPSPOWER_SHIFT_CONSTANT) { /* direct & inverse iteration */
    if (power->shift_type == EPS_POWER_SHIFT_CONSTANT) { /* direct & inverse iteration */
 
 
      /* approximate eigenvalue is the Rayleigh quotient */
      /* approximate eigenvalue is the Rayleigh quotient */
      eps->eigr[eps->nconv] = theta;
      eps->eigr[eps->nconv] = theta;
 
 
      /* compute relative errors (right and left) */
      /* compute relative errors (right and left) */
Line 303... Line 303...
      if (eps->errest[eps->nconv]<eps->tol && eps->errest_left[eps->nconv]<eps->tol) {
      if (eps->errest[eps->nconv]<eps->tol && eps->errest_left[eps->nconv]<eps->tol) {
        rho = sigma; /* if converged, restore original shift */
        rho = sigma; /* if converged, restore original shift */
        ierr = STSetShift(eps->OP,rho);CHKERRQ(ierr);
        ierr = STSetShift(eps->OP,rho);CHKERRQ(ierr);
      } else {
      } else {
        rho = rho + theta/(delta*delta);  /* Rayleigh quotient R(v,w) */
        rho = rho + theta/(delta*delta);  /* Rayleigh quotient R(v,w) */
        if (power->shift_type == EPSPOWER_SHIFT_WILKINSON) {
        if (power->shift_type == EPS_POWER_SHIFT_WILKINSON) {
#if defined(SLEPC_MISSING_LAPACK_LAEV2)
#if defined(SLEPC_MISSING_LAPACK_LAEV2)
          SETERRQ(PETSC_ERR_SUP,"LAEV2 - Lapack routine is unavailable.");
          SETERRQ(PETSC_ERR_SUP,"LAEV2 - Lapack routine is unavailable.");
#else
#else
          /* beta1 is the norm of the residual associated to R(v,w) */
          /* beta1 is the norm of the residual associated to R(v,w) */
          ierr = VecAXPY(v,-theta/(delta*delta),y);CHKERRQ(ierr);
          ierr = VecAXPY(v,-theta/(delta*delta),y);CHKERRQ(ierr);
Line 382... Line 382...
{
{
  PetscErrorCode ierr;
  PetscErrorCode ierr;
  EPS_POWER *power = (EPS_POWER *)eps->data;
  EPS_POWER *power = (EPS_POWER *)eps->data;
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  if (power->shift_type == EPSPOWER_SHIFT_CONSTANT) {
  if (power->shift_type == EPS_POWER_SHIFT_CONSTANT) {
    ierr = EPSBackTransform_Default(eps);CHKERRQ(ierr);
    ierr = EPSBackTransform_Default(eps);CHKERRQ(ierr);
  }
  }
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
 
 
Line 402... Line 402...
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  ierr = PetscOptionsHead("POWER options");CHKERRQ(ierr);
  ierr = PetscOptionsHead("POWER options");CHKERRQ(ierr);
  ierr = PetscOptionsEList("-eps_power_shift_type","Shift type","EPSPowerSetShiftType",shift_list,3,shift_list[power->shift_type],&i,&flg);CHKERRQ(ierr);
  ierr = PetscOptionsEList("-eps_power_shift_type","Shift type","EPSPowerSetShiftType",shift_list,3,shift_list[power->shift_type],&i,&flg);CHKERRQ(ierr);
  if (flg ) power->shift_type = (EPSPowerShiftType)i;
  if (flg ) power->shift_type = (EPSPowerShiftType)i;
  if (power->shift_type != EPSPOWER_SHIFT_CONSTANT) {
  if (power->shift_type != EPS_POWER_SHIFT_CONSTANT) {
    ierr = STSetType(eps->OP,STSINV);CHKERRQ(ierr);
    ierr = STSetType(eps->OP,STSINV);CHKERRQ(ierr);
  }
  }
  ierr = PetscOptionsTail();CHKERRQ(ierr);
  ierr = PetscOptionsTail();CHKERRQ(ierr);
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
Line 418... Line 418...
{
{
  EPS_POWER *power = (EPS_POWER *)eps->data;
  EPS_POWER *power = (EPS_POWER *)eps->data;
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  switch (shift) {
  switch (shift) {
    case EPSPOWER_SHIFT_CONSTANT:
    case EPS_POWER_SHIFT_CONSTANT:
    case EPSPOWER_SHIFT_RAYLEIGH:
    case EPS_POWER_SHIFT_RAYLEIGH:
    case EPSPOWER_SHIFT_WILKINSON:
    case EPS_POWER_SHIFT_WILKINSON:
      power->shift_type = shift;
      power->shift_type = shift;
      break;
      break;
    default:
    default:
      SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid shift type");
      SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid shift type");
  }
  }
Line 448... Line 448...
   Options Database Key:
   Options Database Key:
.  -eps_power_shift_type - Sets the shift type (either 'constant' or
.  -eps_power_shift_type - Sets the shift type (either 'constant' or
                           'rayleigh' or 'wilkinson')
                           'rayleigh' or 'wilkinson')
 
 
   Notes:
   Notes:
   By default, shifts are constant (EPSPOWER_SHIFT_CONSTANT) and the iteration
   By default, shifts are constant (EPS_POWER_SHIFT_CONSTANT) and the iteration
   is the simple power method (or inverse iteration if a shift-and-invert
   is the simple power method (or inverse iteration if a shift-and-invert
   transformation is being used).
   transformation is being used).
 
 
   A variable shift can be specified (EPSPOWER_SHIFT_RAYLEIGH or
   A variable shift can be specified (EPS_POWER_SHIFT_RAYLEIGH or
   EPSPOWER_SHIFT_WILKINSON). In this case, the iteration behaves rather like
   EPS_POWER_SHIFT_WILKINSON). In this case, the iteration behaves rather like
   a cubic converging method as RQI. See the users manual for details.
   a cubic converging method as RQI. See the users manual for details.
   
   
   Level: advanced
   Level: advanced
 
 
.seealso: EPSPowerGetShiftType(), STSetShift(), EPSPowerShiftType
.seealso: EPSPowerGetShiftType(), STSetShift(), EPSPowerShiftType
Line 542... Line 542...
  const char     *shift_list[3] = { "constant", "rayleigh", "wilkinson" };
  const char     *shift_list[3] = { "constant", "rayleigh", "wilkinson" };
 
 
  PetscFunctionBegin;
  PetscFunctionBegin;
  ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
  ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
  if (!isascii) {
  if (!isascii) {
    SETERRQ1(1,"Viewer type %s not supported for EPSPOWER",((PetscObject)viewer)->type_name);
    SETERRQ1(1,"Viewer type %s not supported for EPS_POWER",((PetscObject)viewer)->type_name);
  }  
  }  
  ierr = PetscViewerASCIIPrintf(viewer,"shift type: %s\n",shift_list[power->shift_type]);CHKERRQ(ierr);
  ierr = PetscViewerASCIIPrintf(viewer,"shift type: %s\n",shift_list[power->shift_type]);CHKERRQ(ierr);
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
 
 
Line 568... Line 568...
  eps->ops->setfromoptions       = EPSSetFromOptions_POWER;
  eps->ops->setfromoptions       = EPSSetFromOptions_POWER;
  eps->ops->destroy              = EPSDestroy_POWER;
  eps->ops->destroy              = EPSDestroy_POWER;
  eps->ops->view                 = EPSView_POWER;
  eps->ops->view                 = EPSView_POWER;
  eps->ops->backtransform        = EPSBackTransform_POWER;
  eps->ops->backtransform        = EPSBackTransform_POWER;
  eps->ops->computevectors       = EPSComputeVectors_Default;
  eps->ops->computevectors       = EPSComputeVectors_Default;
  power->shift_type              = EPSPOWER_SHIFT_CONSTANT;
  power->shift_type              = EPS_POWER_SHIFT_CONSTANT;
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSPowerSetShiftType_C","EPSPowerSetShiftType_POWER",EPSPowerSetShiftType_POWER);CHKERRQ(ierr);
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSPowerSetShiftType_C","EPSPowerSetShiftType_POWER",EPSPowerSetShiftType_POWER);CHKERRQ(ierr);
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSPowerGetShiftType_C","EPSPowerGetShiftType_POWER",EPSPowerGetShiftType_POWER);CHKERRQ(ierr);
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSPowerGetShiftType_C","EPSPowerGetShiftType_POWER",EPSPowerGetShiftType_POWER);CHKERRQ(ierr);
  PetscFunctionReturn(0);
  PetscFunctionReturn(0);
}
}
EXTERN_C_END
EXTERN_C_END