Subversion Repositories slepc-dev

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
    Shift spectral transformation, applies (A + sigma I) as operator, or
    inv(B)(A + sigma B) for generalized problems
*/

#include "src/st/stimpl.h"          /*I "slepcst.h" I*/

#undef __FUNCT__  
#define __FUNCT__ "STApply_Shift"
int STApply_Shift(ST st,Vec x,Vec y)
{
  int    ierr;
  Vec    w;

  PetscFunctionBegin;
  if (st->B) {
    /* generalized eigenproblem: y = (B^-1 A + sI) x */
    w = (Vec) st->data;
    ierr = MatMult(st->A,x,w);CHKERRQ(ierr);
    ierr = STAssociatedSLESSolve(st,w,y);CHKERRQ(ierr);
    ierr = VecAXPY(&st->sigma,x,y);CHKERRQ(ierr);
  }
  else {
    /* standard eigenproblem: y = (A + sI) x */
    ierr = MatMult(st->A,x,y);CHKERRQ(ierr);
    ierr = VecAXPY(&st->sigma,x,y);CHKERRQ(ierr);
  }
  PetscFunctionReturn(0);
}

#undef __FUNCT__  
#define __FUNCT__ "STBackTransform_Shift"
int STBackTransform_Shift(ST st,PetscScalar *eigr,PetscScalar *eigi)
{
  PetscFunctionBegin;
  if (eigr) *eigr -= st->sigma;
  PetscFunctionReturn(0);
}

#undef __FUNCT__  
#define __FUNCT__ "STSetUp_Shift"
static int STSetUp_Shift(ST st)
{
  int     ierr;
  Vec     w;

  PetscFunctionBegin;
  if (st->sles) {
    ierr = VecDuplicate(st->vec,&w);CHKERRQ(ierr);
    st->data = (void *) w;
    ierr = SLESSetUp(st->sles,st->vec,st->vec);CHKERRQ(ierr);
  }
  PetscFunctionReturn(0);
}

#undef __FUNCT__  
#define __FUNCT__ "STDestroy_Shift"
static int STDestroy_Shift(ST st)
{
  int      ierr;
  Vec      w;

  PetscFunctionBegin;
  if (st->data) {
    w = (Vec) st->data;
    ierr = VecDestroy(w);CHKERRQ(ierr);
  }
  PetscFunctionReturn(0);
}

EXTERN_C_BEGIN
#undef __FUNCT__  
#define __FUNCT__ "STCreate_Shift"
int STCreate_Shift(ST st)
{
  int     ierr;
  char    *prefix;

  PetscFunctionBegin;
  st->numberofshifts   = 1;
  st->ops->apply       = STApply_Shift;
  st->ops->backtr      = STBackTransform_Shift;
  st->ops->destroy     = STDestroy_Shift;
  st->ops->setup       = STSetUp_Shift;

  if (st->B) {
    ierr = SLESCreate(st->comm,&st->sles);CHKERRQ(ierr);
    ierr = STGetOptionsPrefix(st,&prefix);CHKERRQ(ierr);
    ierr = SLESSetOptionsPrefix(st->sles,prefix);CHKERRQ(ierr);
    ierr = SLESAppendOptionsPrefix(st->sles,"st_");CHKERRQ(ierr);
    ierr = SLESSetOperators(st->sles,st->B,st->B,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
  }

  PetscFunctionReturn(0);
}
EXTERN_C_END