Hello,

I am new to Slepc and trying to work out the eigenvalues and eigenvectors of my 
Jacobian matrix. I am using a shell matrix to work out the matrix-vector 
product and I am using the default Krylov-schur method.

My first attempt was not successful and I got the following errors:

[0]PETSC ERROR: --------------------- Error Message 
--------------------------------------------------------------
[0]PETSC ERROR: Missing or incorrect user input
[0]PETSC ERROR: The inner product is not well defined: indefinite matrix
[0]PETSC ERROR: See https://petsc.org/release/faq/ for trouble shooting.
[0]PETSC ERROR: Petsc Release Version 3.17.4, unknown
[0]PETSC ERROR: cfdtest on a arch-debug named ming by feng Mon Aug 22 19:21:41 
2022
[0]PETSC ERROR: Configure options --with-cc=mpicc --with-cxx=mpicxx --with-fc=0 
PETSC_ARCH=arch-debug
[0]PETSC ERROR: #1 BV_SafeSqrt() at 
/home/feng/cfd/slepc-3.17.1/include/slepc/private/bvimpl.h:130
[0]PETSC ERROR: #2 BV_SquareRoot_Default() at 
/home/feng/cfd/slepc-3.17.1/include/slepc/private/bvimpl.h:365
[0]PETSC ERROR: #3 BVOrthogonalizeCGS1() at 
/home/feng/cfd/slepc-3.17.1/src/sys/classes/bv/interface/bvorthog.c:101
[0]PETSC ERROR: #4 BVOrthogonalizeGS() at 
/home/feng/cfd/slepc-3.17.1/src/sys/classes/bv/interface/bvorthog.c:177
[0]PETSC ERROR: #5 BVOrthonormalizeColumn() at 
/home/feng/cfd/slepc-3.17.1/src/sys/classes/bv/interface/bvorthog.c:402
[0]PETSC ERROR: #6 BVMatArnoldi() at 
/home/feng/cfd/slepc-3.17.1/src/sys/classes/bv/interface/bvkrylov.c:91
[0]PETSC ERROR: #7 EPSSolve_KrylovSchur_Default() at 
/home/feng/cfd/slepc-3.17.1/src/eps/impls/krylov/krylovschur/krylovschur.c:261
[0]PETSC ERROR: #8 EPSSolve() at 
/home/feng/cfd/slepc-3.17.1/src/eps/interface/epssolve.c:147
[0]PETSC ERROR: #9 slepc_eigen_comp() at domain/cfd/slepc_eigen_solve.cpp:77

Could someone please shine some light on this? I have also attached my code. 
The code is part of my big library and I cannot attach the whole code, sorry 
about this. but I am happy to provide more information. The attached code has 
some arrangements for halo exchange, but for the moment, it assumes it is a 
serial run.

Many thanks,
Feng
using namespace std;

#  include <iomanip>      // std::setprecision
#  include <domain/cfd/domain.h>

#ifdef PETSC

   PetscErrorCode cFdDomain::slepc_eigen_comp()
  {
      cout << "slepc_eigen_solve\n";
      PetscErrorCode ierr;
      Mat            slepc_A_mf;      /* eigenvalue problem matrix */
      Int iq, iqs, iqe;
      PetscInt blocksize;
      MPI_Comm* A_COMM_WORLD;
      PetscInt maxneig=8;
      PetscInt       nev;
      EPS            eps;             /* eigenproblem solver context */
      EPSType        type;
      PetscViewer    viewer;

      movegrid();
      frame();
      weights();

      cout << "show vtk file\n";
      vtk();


      A_COMM_WORLD = dev->getcomm();

      dof->range( dev->getrank(), &iqs,&iqe );

      //number of ghost cells and their global indexes (in the new numbering)
      ig_mat = dof->get_igmat();
      ighost       = new Int [dof->size()];
      ighost_local = new Int [dof->size()];
      ilocal       = new Int [dof->size()];
      nghost=0;
      nlocal=0;
      for(iq=0; iq<dof->size(); iq++)
     {
         if(iq>=iqs && iq<iqe)
        {
            //non-halo cells
            ilocal[nlocal] = iq;
            nlocal++;
        }
         else
        {
            ighost[nghost] = ig_mat[iq];
            ighost_local[nghost] = iq;
            nghost++;
        }
     }
      blocksize = nv;

      cout << nlocal << " " << blocksize << "\n";
//create shell matrix
      PetscCall(MatCreateShell(*A_COMM_WORLD, nlocal*blocksize, nlocal*blocksize, PETSC_DETERMINE, PETSC_DETERMINE, this, &slepc_A_mf));
      PetscCall(MatShellSetOperation(slepc_A_mf,MATOP_MULT,(void(*)(void))mymult_slepc));

// Create eigensolver context
      PetscCall(EPSCreate(*A_COMM_WORLD,&eps));

// Set operators. In this case, it is a standard eigenvalue problem
      PetscCall(EPSSetOperators(eps,slepc_A_mf,NULL));
      PetscCall(EPSSetProblemType(eps,EPS_NHEP));

// Ask for the rightmost eigenvalues
      PetscCall(EPSSetWhichEigenpairs(eps,EPS_LARGEST_REAL));

// Set other solver options at runtime
      PetscCall(EPSSetFromOptions(eps));

// Solve the eigensystem
      PetscCall(EPSSolve(eps));

  /*
     Optional: Get some information from the solver and display it
  */
      PetscCall(EPSGetType(eps,&type));
      PetscCall(PetscPrintf(*A_COMM_WORLD," Solution method: %s\n\n",type));
      PetscCall(EPSGetDimensions(eps,&nev,NULL,NULL));
      PetscCall(PetscPrintf(*A_COMM_WORLD," Number of requested eigenvalues: %" PetscInt_FMT "\n",nev));

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                    Display solution and clean up
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /* show detailed info unless -terse option is given by user */
      PetscCall(PetscViewerASCIIGetStdout(*A_COMM_WORLD,&viewer));
      PetscCall(PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL));
      PetscCall(EPSConvergedReasonView(eps,viewer));
      PetscCall(EPSErrorView(eps,EPS_ERROR_RELATIVE,viewer));
      PetscCall(PetscViewerPopFormat(viewer));
      PetscCall(EPSDestroy(&eps));
      PetscCall(MatDestroy(&slepc_A_mf));

      ierr=0;
      return ierr;
  }

   PetscErrorCode cFdDomain::mymult_slepc(Mat m ,Vec x, Vec y)
  {
      PetscErrorCode ierr;
      void *ctx;
      cFdDomain *myctx;
      Vec localin;

      MatShellGetContext(m, &ctx);
      myctx = (cFdDomain*)ctx;

//      PetscCall(VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD));
//      PetscCall(VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD));
//      PetscCall(VecGhostGetLocalForm(x,&localin));

      ierr = myctx->petsc_set_fd_dq(x); CHKERRQ(ierr);
      ierr = myctx->slepc_fd_rhs2(y); CHKERRQ(ierr);

//      VecGhostRestoreLocalForm(x,&localin);

      return ierr;
  }

   PetscErrorCode cFdDomain::slepc_fd_rhs2(Vec var)
  {
      Int iqs, iqe;
      Int iv, iq, jq;
      Real delta_rhs;
      PetscErrorCode ierr;
      PetscScalar *array;
      Real eps;
      Real dq_norm;

      dof->range( dev->getrank(), &iqs,&iqe );

      dq_norm = 0;
      for(iq=iqs; iq<iqe; iq++)
     {
         for(iv=0; iv<nv; iv++)
        {
            dq_norm += dq[iv][iq]*dq[iv][iq];
        }
     }
      dev->gsum(1, &dq_norm);
      dq_norm = sqrt(dq_norm/dof->gsize());
      //eps  = sqrt(1+csv_mag_fd)*1.e-4/dq_norm;
      eps  = 1.e-7/dq_norm;
      cout << eps << "\n";

//compute rhs with unperturbed flow states
      setv( 0,dof->size(), nv, 0., rhs );

      grad( q,dqdx );
      gradb( q,dqdx );

      gtrhf( rhs );
      gtrhm( rhs );
      gtrhv( rhs );

//perturb q, halo and non-halo cells
//convert to primitive variable perturbations
      fld->dvar( 0,dof->size(), q, aux, dq, daux );
      for(iv=0; iv<nv; iv++)
     {
         for(iq=0; iq<dof->size(); iq++)
        {
            q[iv][iq] += daux[iv][iq]*eps;
        }
     } 

//compute rhs with perturbed flow states
      setv( 0,dof->size(), nv, 0., wrkq );

      grad( q,dqdx );
      gradb( q,dqdx );

      gtrhf( wrkq );
      gtrhm( wrkq );
      gtrhv( wrkq );

//matrix-vector product
      ierr = VecGetArray(var,&array); CHKERRQ(ierr);

      for(iv=0; iv<nv; iv++)  
     {
         for(iq=0; iq<nlocal; iq++) 
        {
            jq = ilocal[iq];
            array[iv + nv*iq] = (wrkq[iv][jq] - rhs[iv][jq])/eps;
        }
     }

      ierr = VecRestoreArray(var,&array); CHKERRQ(ierr);

///reset q
      for(iv=0; iv<nv; iv++)
     {
         for(iq=0; iq<dof->size(); iq++)
        {
            q[iv][iq] -= daux[iv][iq]*eps;
        }
     } 

      ierr = 0;
      return ierr;
  }

#endif

Reply via email to