[petsc-users] Slepc eigen value solver gives strange behavior

Gong Ding gdiso at ustc.edu
Mon Apr 4 22:07:32 CDT 2011


Hi,
I use slepc eigen value solver to evaluate the eigen values of jacobian matrix on each nonlinear iteration.

First, I create the EPS structure and set the operator to jacobian matrix. And then call the EPSSolve in the SNES build 
jacobian matrix functuion. This method create EPS once, call EPSSolve many times. However, it seems EPSSolve only work at
first time, and result eigen value never changes (however, relative error becomes larger and larger) in the following solve procedure. 

Then I create EPS each time in the SNES build jacobian matrix functuion, do EPSSolve and delete EPS at the end of function.
This method gives eigen value for the jacobian matrix with small relative error ~1e-8. Of course, create and destroy the EPS solver each time
is not efficient.

Does something get wrong in the first method? 

The code I used is attached here

  // create the EPS solver for smallest and largest eigen value
  EPS            eps_s;
  EPS            eps_l;

  FVM_NonlinearSolver & nonlinear_solver = dynamic_cast<FVM_NonlinearSolver &>(_solver);
  Mat & J = nonlinear_solver.jacobian_matrix();

  // create eigen value problem solver
  EPSCreate(PETSC_COMM_WORLD, &eps_s);
  EPSCreate(PETSC_COMM_WORLD, &eps_l);
  // Set operator
  EPSSetOperators(eps_s, J, PETSC_NULL);
  EPSSetOperators(eps_l, J, PETSC_NULL);

  // calculate smallest and largest eigen value
  EPSSetWhichEigenpairs(eps_s, EPS_SMALLEST_MAGNITUDE);
  EPSSetWhichEigenpairs(eps_l, EPS_LARGEST_MAGNITUDE);

  // shift-and-invert spectral transformation to enhance convergence of eigenvalues near zero
  ST st_s;
  EPSGetST(eps_s, &st_s);
  STSetType(st_s, STSINVERT);


  // Set solver parameters at runtime
  EPSSetFromOptions(eps_s);
  EPSSetFromOptions(eps_l);


///////////////////////////////////////////////////////////////////////////////
 
  // this part is called after jacobian matrix assemly

  PetscScalar kr_s, ki_s;
  PetscScalar kr_l, ki_l;
  PetscReal error_s;
  PetscReal error_l;
  PetscInt nconv_s;
  PetscInt nconv_l;

  // get the smallest eigen value
  EPSSolve( eps_s );
  EPSGetConverged( eps_s, &nconv_s );
  if( nconv_s > 0 )
  {
    EPSGetEigenvalue( eps_s, 0, &kr_s, &ki_s );
    EPSComputeRelativeError( eps_s, 0, &error_s );
  }

  // get the largest eigen value
  EPSSolve( eps_l );
  EPSGetConverged( eps_l, &nconv_l );
  if( nconv_l > 0 )
  {
    EPSGetEigenvalue( eps_l, 0, &kr_l, &ki_l );
    EPSComputeRelativeError( eps_l, 0, &error_l );
  }




More information about the petsc-users mailing list