ARPACK调用SuperLU例程错了吗?

时间:2014-08-15 17:42:28

标签: c++ static-libraries numerical-methods finite-element-analysis arpack

当使用众所周知的ARPACK库来解决大型,稀疏的广义特征值问题(这里,我正在使用C ++接口)时,我注意到在尝试调用时非常奇怪的解决方案

nev = 10 // number of eigenvalues to calculate
ARluSymGenEig<double> eigenvalueProblem('C', nev, A, B, 5., "SM");
eigenvalueProblem.FindEigenvectors();

在数学上:使用线性元素在单位平方[0,1] ^ 2上的5x5网格上求解Cayley模式中的拉普拉斯 - 特征值问题。 'A'是相应的刚度 - 'B'是质量矩阵。没有输入Dirchlet边界条件,因此这就是Neumann问题。
我只对前10个最小的特征对感兴趣,因此“SM”(最小幅度); “5”。是一些转移参数。

我得到了这个输出:

~/LapEVSol$ ./main SquareGrid.txt meshoutput.vtk 
Reading eigenvalue problem from file SquareGrid.txt...
** On entry to dgstrs, parameter number  6 had an illegal value
** On entry to dgstrs, parameter number  6 had an illegal value
** On entry to dgstrs, parameter number  6 had an illegal value
...
** On entry to dgstrs, parameter number  6 had an illegal value
** On entry to dgstrs, parameter number  6 had an illegal value
** On entry to dgstrs, parameter number  6 had an illegal value

Done!
Dimension of the system            : 25
Number of 'requested' eigenvalues  : 10
Number of 'converged' eigenvalues  : 10
Number of Arnoldi vectors generated: 21
Number of iterations taken         : 10

Eigenvalues:
  lambda[1]: -90.5854
  lambda[2]: -16.2358
  lambda[3]: -11.0635
  lambda[4]: -8.95837
  lambda[5]: -5.78369
  lambda[6]: 16.5812
  lambda[7]: 16.9097
  lambda[8]: 36.4766
  lambda[9]: 62.1445
  lambda[10]: 66.4824

||A*x(0) - lambda(0)*B*x(0)||: 0.252506
||A*x(1) - lambda(1)*B*x(1)||: 0.75909
||A*x(2) - lambda(2)*B*x(2)||: 0.911785
||A*x(3) - lambda(3)*B*x(3)||: 0.901433
||A*x(4) - lambda(4)*B*x(4)||: 1.20555
||A*x(5) - lambda(5)*B*x(5)||: 0.980946
||A*x(6) - lambda(6)*B*x(6)||: 0.985718
||A*x(7) - lambda(7)*B*x(7)||: 0.26326
||A*x(8) - lambda(8)*B*x(8)||: 0.204725
||A*x(9) - lambda(9)*B*x(9)||: 0.113176

当然这输出是完全错误的。特征值应该都是非负的,大概是0,10,10,22,47,47等。带有dgstrs()的错误消息导致假设,ARPACK调用SuperLU例程dgstrs()错误解决一些线性系统。在代码中,ARPACK试图调用

arlspen.h中的

函数模板void ARluSymPencil :: MultInvAsBv(ARTYPE v,ARTYPE * w):*

Create_Dense_Matrix(&RHS, A->nrows(), 1, w, A->nrows(), SLU_DN, SLU_GE);
gstrs(trans, &L, &U, permc, permr, &RHS, &stat, &info);
superluc.h中的

inline void gstrs(trans_t trans, SuperMatrix *L, SuperMatrix *U,
        int *perm_c, int *perm_r, SuperMatrix *B, SuperLUStat_t* stat, int *info)
{

  if (L->Dtype == SLU_D) {       // calling the double precision routine.
    dgstrs(trans,L,U,perm_c,perm_r,B,stat,info);
  }
...
}


inline void Create_Dense_Matrix(SuperMatrix* A, int m, int n, double* x,
                            int ldx, Stype_t S, Mtype_t M)
{

  dCreate_Dense_Matrix(A,m,n,x,ldx,S,SLU_D,M);

} // Create_Dense_Matrix (double).

dgstrs()和dCreate_Dense_Matrix()是用Fortran编写的SuperLU例程,因此难以在调试中进一步跟踪。错误消息恰好发生在dgstrs()中,并且说第六个参数有问题,即SuperMatrix B. B在Create_Dense_Matrix()函数中创建,实际上看起来有点奇怪,因为参数“.. 。,A-> nrows(),1,...,A-> nrows()“,它基本上创建了一个密集的”m次1“矩阵,其前导维度为n(其中m是行数和n是输入矩阵A)的列数 - 我希望这是不同的。

即使在ARPACK ++给出的示例中,例如lsymgreg.cc(它基本上调用与我的问题完全相同的函数),输出也会给出错误的负特征值,并且具有相同的dgstrs() - 错误。并且所有测试的问题都具有非常小的尺寸(25x25矩阵),因此不存在任何稳定性问题并且对称特征值问题具有良好的条件。

是否曾经遇到过与ARPACK / ARPACK ++相同的问题,或者知道原因是什么?



编辑:以下是有关此问题的两个主要功能的更多信息:
首先在 argsym.h中找到FindArnoldiBasis()

template<class ARFLOAT, class ARFOP, class ARFB>
int ARSymGenEig<ARFLOAT, ARFOP, ARFB>::FindArnoldiBasis()
{

  ARFLOAT* temp;

  if (this->mode != 5) {  // Using base function if not in Cayley mode.
        return ARGenEig<ARFLOAT, ARFLOAT, ARFOP, ARFB>::FindArnoldiBasis();
  }
  else {

    temp = new ARFLOAT[this->n+1];

    if (!this->BasisOK) this->Restart();

    // Changing to auto shift mode.

    if (!this->AutoShift) {
      ArpackError::Set(ArpackError::CHANGING_AUTOSHIFT, "FindArnoldiBasis");
      this->AutoShift=true;
    }

    // ARPACK main loop.

    while (!this->BasisOK) {

      // Calling Aupp.

      try { this->TakeStep(); }
      catch (ArpackError) {
        ArpackError(ArpackError::CANNOT_FIND_BASIS, "FindArnoldiBasis");
        delete[] temp;
        return 0;
      }

      switch (this->ido) {
      case -1:

        // Performing y <- B*x for the first time.

        this->ipntr[3] = this->ipntr[2]+this->n; // not a clever idea, but...
        (this->objB->*(this->MultBx))(&this->workd[this->ipntr[1]],&this->workd[this->ipntr[3]]);

      case  1:

        // Performing y <- OP*(A+sigma*B)*x, B*x is already available.

        (this->objB->*MultAx)(&this->workd[this->ipntr[1]], temp);
        axpy(this->n, this->sigmaR, &this->workd[this->ipntr[3]], 1, temp, 1);
        (this->objOP->*(this->MultOPx))(temp, &this->workd[this->ipntr[2]]);
        break;

      case  2:

        // Performing y <- B*x.

        (this->objB->*(this->MultBx))(&this->workd[this->ipntr[1]],&this->workd[this->ipntr[2]]);

      }
    }

    delete[] temp;

    return this->nconv;
  }

 // FindArnoldiBasis.

此方法调用(在案例1中) MultOPx(),它调用 MultInvAsBv(),因此 gstrs()

template<class ARTYPE>
void ARluSymPencil<ARTYPE>::MultInvAsBv(ARTYPE* v, ARTYPE* w)
{

  // Quitting the function if AsB was not factored.

  if (!IsFactored()) {
    throw ArpackError(ArpackError::NOT_FACTORED_MATRIX,
                      "ARluSymPencil::MultInvAsBv");
  }

  // Solving AsB.w = v.

  int         info;
  SuperMatrix RHS;

  copy(A->nrows(), v, 1, w, 1);
  Create_Dense_Matrix(&RHS, A->nrows(), 1, w, A->nrows(), SLU_DN, SLU_GE);
  //  gstrs("N", &L, &U, permr, permc, &RHS, &info);
  trans_t trans = NOTRANS;
  StatInit(&stat);

  gstrs(trans, &L, &U, permc, permr, &RHS, &stat, &info);

  Destroy_SuperMatrix_Store(&RHS); // delete RHS.Store;

} // MultInvAsBv.

变量L,U,permc和permr位于类ARluSymPencil中,其中包含上述成员函数:

template<class ARTYPE>
class ARluSymPencil
{

 protected:

  bool                   factored;
  int*                   permc;
  int*                   permr;
  char                   part;
  char                   uplo;
  ARluSymMatrix<ARTYPE>* A;
  ARluSymMatrix<ARTYPE>* B;
  SuperMatrix            L;
  SuperMatrix            U;
  SuperLUStat_t stat;

(SuperMatrix和其他一些类型在SuperLU库中定义)

0 个答案:

没有答案