21#include "b2matrix_compressed.H"
26void b2linalg::Matrix<double, b2linalg::Mcompressed_col_constref>::LUFactorization(
27 b2linalg::Matrix<double, b2linalg::Mcompressed_col>& trans_L,
28 b2linalg::Matrix<double, b2linalg::Mcompressed_col>& U, Index& P, Index& Q,
29 Vector<double, Vdense>& R) {
30 if (size1() == 0 || size2() == 0) {
31 trans_L.resize(size2(), size1(), 0);
32 U.resize(size1(), size2(), 0);
39 double Control[UMFPACK_CONTROL];
40 umfpack_dl_defaults(Control);
42 Control[UMFPACK_SCALE] = UMFPACK_SCALE_NONE;
51 if ((status = umfpack_dl_symbolic(
52 size1(), size2(),
reinterpret_cast<long*
>(
const_cast<size_t*
>(si)),
53 reinterpret_cast<long*
>(
const_cast<size_t*
>(index)),
const_cast<double*
>(m),
54 &Symbolic, Control, 0))
56 Exception() <<
"umfpack_dl_symbolic return the error code " << status <<
"." <<
THROW;
59 double info[UMFPACK_INFO];
60 if ((status = umfpack_dl_numeric(
61 reinterpret_cast<long*
>(
const_cast<size_t*
>(si)),
62 reinterpret_cast<long*
>(
const_cast<size_t*
>(index)),
const_cast<double*
>(m),
63 Symbolic, &Numeric, Control, info))
65 Exception() <<
"umfpack_dl_numeric return the error code " << status <<
"." <<
THROW;
75 umfpack_dl_free_symbolic(&Symbolic);
76 long lnz, unz, nrow, ncol, nz_udiag;
77 if ((status = umfpack_dl_get_lunz(&lnz, &unz, &nrow, &ncol, &nz_udiag, Numeric))
79 Exception() <<
"umfpack_dl_get_lunz return the error code " << status <<
"." <<
THROW;
81 long diag = std::min(nrow, ncol);
82 trans_L.resize(diag, nrow, lnz);
83 U.resize(diag, ncol, unz);
88 if ((status = umfpack_dl_get_numeric(
89 reinterpret_cast<long*
>(&trans_L.si[0]),
reinterpret_cast<long*
>(&trans_L.index[0]),
90 &trans_L.m[0],
reinterpret_cast<long*
>(&U.si[0]),
91 reinterpret_cast<long*
>(&U.index[0]), &U.m[0],
reinterpret_cast<long*
>(&P[0]),
92 reinterpret_cast<long*
>(&Q[0]), 0, &do_recip, &R[0], Numeric))
94 Exception() <<
"umfpack_dl_get_numeric return the error code " << status <<
"." <<
THROW;
97 umfpack_dl_free_numeric(&Numeric);
99 if (nz_udiag != diag) { UMFPACK_clean_incomplete_factorization(trans_L, U, nz_udiag, P, Q, R); }
131 for (
size_t i = 0; i != R.size(); ++i) { R[i] = 1.0 / R[i]; }
139void b2linalg::Matrix<std::complex<double>, b2linalg::Mcompressed_col_constref>::LUFactorization(
140 b2linalg::Matrix<std::complex<double>, b2linalg::Mcompressed_col>& trans_L,
141 b2linalg::Matrix<std::complex<double>, b2linalg::Mcompressed_col>& U, Index& P, Index& Q,
142 b2linalg::Vector<double, b2linalg::Vdense>& R) {
143 if (size1() == 0 || size2() == 0) {
144 trans_L.resize(size2(), size1(), 0);
145 U.resize(size1(), size2(), 0);
154 double Control[UMFPACK_CONTROL];
155 umfpack_zl_defaults(Control);
157 Control[UMFPACK_SCALE] = UMFPACK_SCALE_NONE;
165 if ((status = umfpack_zl_symbolic(
166 size1(), size2(),
reinterpret_cast<long*
>(
const_cast<size_t*
>(si)),
167 reinterpret_cast<long*
>(
const_cast<size_t*
>(index)),
168 reinterpret_cast<double*
>(
const_cast<std::complex<double>*
>(m)), 0, &Symbolic,
171 Exception() <<
"umfpack_zl_symbolic return the error code " << status <<
"." <<
THROW;
174 double info[UMFPACK_INFO];
175 if ((status = umfpack_zl_numeric(
176 reinterpret_cast<long*
>(
const_cast<size_t*
>(si)),
177 reinterpret_cast<long*
>(
const_cast<size_t*
>(index)),
178 reinterpret_cast<double*
>(
const_cast<std::complex<double>*
>(m)), 0, Symbolic,
179 &Numeric, Control, info))
181 Exception() <<
"umfpack_zl_numeric return the error code " << status <<
"." <<
THROW;
191 umfpack_zl_free_symbolic(&Symbolic);
192 long lnz, unz, nrow, ncol, nz_udiag;
193 if ((status = umfpack_zl_get_lunz(&lnz, &unz, &nrow, &ncol, &nz_udiag, Numeric))
195 Exception() <<
"umfpack_zl_get_lunz return the error code " << status <<
"." <<
THROW;
197 long diag = std::min(nrow, ncol);
198 trans_L.resize(diag, nrow, lnz);
199 U.resize(diag, ncol, unz);
204 if ((status = umfpack_zl_get_numeric(
205 reinterpret_cast<long*
>(&trans_L.si[0]),
reinterpret_cast<long*
>(&trans_L.index[0]),
206 reinterpret_cast<double*
>(&trans_L.m[0]), 0,
reinterpret_cast<long*
>(&U.si[0]),
207 reinterpret_cast<long*
>(&U.index[0]),
reinterpret_cast<double*
>(&U.m[0]), 0,
208 reinterpret_cast<long*
>(&P[0]),
reinterpret_cast<long*
>(&Q[0]), 0, 0, &do_recip,
211 Exception() <<
"umfpack_zl_get_numeric return the error code " << status <<
"." <<
THROW;
214 umfpack_zl_free_numeric(&Numeric);
216 if (nz_udiag != diag) { UMFPACK_clean_incomplete_factorization(trans_L, U, nz_udiag, P, Q, R); }
248 for (
size_t i = 0; i != R.size(); ++i) { R[i] = 1.0 / R[i]; }
256void b2linalg::Matrix<b2000::csda<double>, b2linalg::Mcompressed_col_constref>::LUFactorization(
257 b2linalg::Matrix<b2000::csda<double>, b2linalg::Mcompressed_col>& trans_L,
258 b2linalg::Matrix<b2000::csda<double>, b2linalg::Mcompressed_col>& U, Index& P, Index& Q,
259 b2linalg::Vector<double, b2linalg::Vdense>& R) {
260 b2linalg::Matrix<std::complex<double>, Mcompressed_col_constref>* c_this =
261 reinterpret_cast<b2linalg::Matrix<std::complex<double>, Mcompressed_col_constref
>*>(
this);
262 c_this->LUFactorization(
263 reinterpret_cast<b2linalg::Matrix<std::complex<double>, b2linalg::Mcompressed_col
>&>(
265 reinterpret_cast<b2linalg::Matrix<std::complex<double>, b2linalg::Mcompressed_col
>&>(U),
270void b2linalg::Matrix<T, b2linalg::Mcompressed_col_constref>::
271 UMFPACK_clean_incomplete_factorization(
272 b2linalg::Matrix<T, b2linalg::Mcompressed_col>& trans_L,
273 b2linalg::Matrix<T, b2linalg::Mcompressed_col>& U,
const size_t nb_udiag,
274 b2linalg::Index& P, b2linalg::Index& Q, b2linalg::Vector<double, b2linalg::Vdense>& R) {
275 Index perm(U.size1());
278 size_t ptr_0 = nb_udiag;
279 for (
size_t i = 0; i != U.size1(); ++i) {
280 if (U.si[i + 1] - U.si[i] == 0 || U.index[U.si[i + 1] - 1] != i) {
287 Index inv_perm = perm.make_dual();
292 for (
size_t j = 0; j != U.size2(); ++j) {
293 for (
const size_t i_end = U.si[j + 1]; i != i_end; ++i) {
294 size_t& tmp = U.index[i];
299 std::vector<size_t> si_tmp(U.size1() + 1);
301 std::vector<size_t> index_tmp(U.si[U.size1()]);
302 std::vector<T> value_tmp(index_tmp.size());
303 for (
size_t j = 0; j != perm.size(); ++j) {
304 const size_t perm_j = perm[j];
305 const size_t begin = U.si[perm_j];
306 const size_t end = U.si[perm_j + 1];
308 U.index.begin() + begin, U.index.begin() + end, index_tmp.begin() + si_tmp[j]);
309 std::copy(U.m.begin() + begin, U.m.begin() + end, value_tmp.begin() + si_tmp[j]);
310 si_tmp[j + 1] = si_tmp[j] + (end - begin);
312 std::copy(si_tmp.begin(), si_tmp.end(), U.si.begin());
313 std::copy(index_tmp.begin(), index_tmp.end(), U.index.begin());
314 std::copy(value_tmp.begin(), value_tmp.end(), U.m.begin());
320 std::vector<size_t> si_tmp(trans_L.size2() + 1);
326 for (
size_t j = 0; j != trans_L.size2();) {
328 for (
const size_t i_end = trans_L.si[j]; i != i_end; ++i) {
329 const size_t tmp = inv_perm[trans_L.index[i]];
330 if (tmp < nb_udiag) {
331 trans_L.index[i_w] = tmp;
332 trans_L.m[i_w] = trans_L.m[i];
340 std::vector<size_t> index_tmp(si_tmp[trans_L.size2()]);
341 std::vector<T> value_tmp(index_tmp.size());
342 for (
size_t j = 0; j != perm.size(); ++j) {
343 const size_t perm_j = perm[j];
344 const size_t begin = si_tmp[perm_j];
345 const size_t end = si_tmp[perm_j + 1];
347 trans_L.index.begin() + begin, trans_L.index.begin() + end,
348 index_tmp.begin() + trans_L.si[j]);
350 trans_L.m.begin() + begin, trans_L.m.begin() + end,
351 value_tmp.begin() + trans_L.si[j]);
352 trans_L.si[j + 1] = trans_L.si[j] + (end - begin);
354 std::copy(si_tmp.begin() + perm.size(), si_tmp.end(), trans_L.si.begin() + perm.size());
356 const size_t i = si_tmp[perm.size()];
357 const size_t i_end = si_tmp.back();
359 trans_L.index.begin() + i, trans_L.index.begin() + i_end, index_tmp.begin() + i);
360 std::copy(trans_L.m.begin() + i, trans_L.m.begin() + i_end, value_tmp.begin() + i);
362 trans_L.index.swap(index_tmp);
363 trans_L.m.swap(value_tmp);
365 trans_L.s1 = nb_udiag;
369 std::vector<size_t> tmp(perm.size());
370 for (
size_t i = 0; i != perm.size(); ++i) { tmp[i] = P[perm[i]]; }
371 std::copy(tmp.begin(), tmp.begin() + perm.size(), P.begin());
372 for (
size_t i = 0; i != perm.size(); ++i) { tmp[i] = Q[perm[i]]; }
373 std::copy(tmp.begin(), tmp.begin() + perm.size(), Q.begin());
#define THROW
Definition b2exception.H:198
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32
GenericException< UnimplementedError_name > UnimplementedError
Definition b2exception.H:314