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; }
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_; }