示例#1
0
int
BandSPDLinLapackSolver::solve(void)
{
    if (theSOE == 0) {
	opserr << "WARNING BandSPDLinLapackSolver::solve(void)- ";
	opserr << " No LinearSOE object has been set\n";
	return -1;
    }

    int n = theSOE->size;
    int kd = theSOE->half_band -1;
    int ldA = kd +1;
    int nrhs = 1;
    int ldB = n;
    int info;
    double *Aptr = theSOE->A;
    double *Xptr = theSOE->X;
    double *Bptr = theSOE->B;

    // first copy B into X
    for (int i=0; i<n; i++)
	*(Xptr++) = *(Bptr++);
    Xptr = theSOE->X;

    // now solve AX = Y

	

#ifdef _WIN32
    if (theSOE->factored == false) {
	// factor and solve 	
	unsigned int sizeC = 1;
	DPBSV("U", &n,&kd,&nrhs,Aptr,&ldA,Xptr,&ldB,&info);	
    }
      else {
	// solve only using factored matrix	  
	unsigned int sizeC = 1;	
	//DPBTRS("U", sizeC, &n,&kd,&nrhs,Aptr,&ldA,Xptr,&ldB,&info);	
	DPBTRS("U", &n,&kd,&nrhs,Aptr,&ldA,Xptr,&ldB,&info);
    }
#else	
    { if (theSOE->factored == false)          
	dpbsv_("U",&n,&kd,&nrhs,Aptr,&ldA,Xptr,&ldB,&info);
      else
	dpbtrs_("U",&n,&kd,&nrhs,Aptr,&ldA,Xptr,&ldB,&info);
    }
#endif    

    // check if successfull
    if (info != 0) {
	opserr << "WARNING BandSPDLinLapackSolver::solve() - the LAPACK";
	opserr << " routines returned " << info << endln;
	return -info;
    }

    theSOE->factored = true;
    return 0;
}
示例#2
0
        std::vector<double> Linear_equations::LEsolver<Element::Second>()
        {
            // 上三角要素を使う場合
            auto uplo = 'U';

            // 線形方程式の数(行列Aの次数)
            auto n = static_cast<std::int32_t>(n_);

            // 係数行列の帯の中にある対角線より上の部分の個数
            auto kd = 2;

            // 行列{B}の列数。通常通り1
            auto nrhs = 1;

            // 配列ABの1次元目の大きさ(= KD + 1)
            auto nb = kd + 1;

            // 係数行列の帯の外を省略して詰め込んだ2次元配列
            // ピボッティングありのLU分解を行うために(KD + 1)× N必要
            std::vector<double> ab(nb * n);

            for (auto i = 0; i < n; i++) {
                for (auto j = i; j <= i + 2; j++) {
                    if (j == i) {
                        ab[(j) * nb + (kd + i - j)] = a0_[i];
                    }
                    else if (j == i + 1 && j < n - 1) {
                        ab[(j) * nb + (kd + i - j)] = a1_[i];
                    }
                    else if (j == i + 2 && j < n - 2) {
                        ab[(j) * nb + (kd + i - j)] = a2_[i];
                    }
                }
            }

            std::int32_t info;
            dpbsv_(
                &uplo,      // 上三角要素を使う場合                    
                &n,         // 線形方程式の数(行列Aの次数)
                &kd,        // 係数行列の帯の中にある対角線より上の部分の個数
                &nrhs,      // 行列{B}の列数。通常通り1
                ab.data(),  // 係数行列(input),コレスキー分解の結果(output)
                &nb,        // 配列ABの1次元目の大きさ(=KD+1) 
                b_.data(),  // 方程式の右辺(input),方程式の解(output)
                &n,         // 行列Bの1次元目の大きさ(=N)
                &info);

            if (info > 0) {
                throw std::logic_error("U is singular");
            }
            else if (info < 0) {
                auto const str = (boost::format("%d-th argument has illegal value") % std::abs(info)).str();

                throw std::invalid_argument(str);
            }

            return b_;
        }