17 template <
typename _Type>
20 m_detSign(0), m_monitorDet(false) {
24 if((m_version !=
"lapack") && (m_version !=
"native")) {
26 problem =
"The BandedLinearSystem has been instantiated with an unrecognised\n";
27 problem +=
"request for a solver type. Options are 'native' or 'lapack'. \n";
33 template <
typename _Type>
35 if(
"lapack" == m_version) {
43 template <
typename _Type>
46 problem =
"The solve method for a BandedLinearSystem has not been implemented\n";
47 problem +=
"for the element type used here. \n";
53 void BandedLinearSystem<double>::solve_lapack() {
55 std::string problem =
"The BandedLinearSystem<double>::solve_lapack method has been called\n";
56 problem +=
"but the compiler option -DLAPACK was not provided when\n";
57 problem +=
"the library was built and so LAPACK support is not available.";
58 throw ExceptionExternal(problem);
60 const std::size_t N = m_pA -> nrows();
61 const std::size_t K = 1;
62 const std::size_t L = m_pA -> noffdiag();
63 const std::size_t LDAB = 3 * L + 1;
65 std::vector<int> pivots(N);
68 LAPACK_DGBSV(N, L, L, K, m_pA -> base(), LDAB, &pivots[ 0 ], &(m_pB ->
operator[](0)), N, info);
71 std::string problem(
" The BandedLinearSystem::solve_lapack method has detected a failure. \n");
72 throw ExceptionExternal(problem, info);
76 m_detSign = signature(pivots);
78 for(std::size_t i = 0; i < N; ++i) {
79 if((*m_pA)(i, i) < 0.0) {
91 std::string problem =
"The BandedLinearSystem<double>::re_solve_lapack method has been called\n";
92 problem +=
"but the compiler option -DLAPACK was not provided when\n";
93 problem +=
"the library was built and so LAPACK support is not available.";
96 const std::size_t N = m_pA -> nrows();
97 const std::size_t K = 1;
98 const std::size_t L = m_pA -> noffdiag();
99 const std::size_t LDAB = 3 * L + 1;
103 LAPACK_DGBTRS((
char*)
"N", N, L, L, K, m_pA -> base(), LDAB, &m_pivots[ 0 ], &(m_pB ->
operator[](0)), N, info);
105 std::string problem(
" The BandedLinearSystem::re_solve_lapack method has detected a failure. \n");
116 std::string problem =
"The BandedLinearSystem<D_complex>::solve_lapack method has been called\n";
117 problem +=
"but the compiler option -DLAPACK was not provided when\n";
118 problem +=
"the library was built and so LAPACK support is not available.";
121 const std::size_t N = m_pA -> nrows();
122 const std::size_t K = 1;
123 const std::size_t L = m_pA -> noffdiag();
124 const std::size_t LDAB = 3 * L + 1;
126 std::vector<int> pivots(N);
130 LAPACK_ZGBSV(N, L, L, K, m_pA -> base(), LDAB, &pivots[ 0 ], &
reinterpret_cast<double(&)[2]
>(m_pB ->
operator[](0))[0], N, info);
132 std::string problem(
" The BandedLinearSystem::solve_lapack method has detected a failure. \n");
139 template <
typename _Type>
140 void BandedLinearSystem<_Type>::solve_native() {
144 const unsigned L = m_pA -> noffdiag();
145 const std::size_t N = m_pA -> nrows();
147 for(std::size_t l = 0 ; l < N - 1 ; ++l) {
148 _Type diag_entry = (*m_pA)(l, l);
152 const std::size_t row_end = std::min(N, l + 1 * L + 1);
153 const std::size_t col_end = std::min(N, l + 2 * L + 1);
156 std::size_t max_row = l;
158 for(std::size_t row = l + 1; row < row_end; ++row) {
159 if(std::abs((*m_pA)(row, l)) > std::abs(diag_entry)) {
160 diag_entry = (*m_pA)(row, l);
167 m_pA -> row_swap(l, max_row);
169 m_pB -> swap(l, max_row);
172 for(std::size_t row = l + 1 ; row < row_end; ++row) {
174 const _Type mult = (*m_pA)(row, l) / diag_entry;
176 for(std::size_t col = l; col < col_end; ++col) {
177 (*m_pA)(row, col) -= (*m_pA)(l, col) * mult;
180 m_pB -> operator[](row) -= mult * m_pB -> operator[](l);
186 for(std::size_t i = 0; i < N; ++i) {
187 if(lt(m_pA ->
operator()(i, i))) {
197 template <
typename _Type>
198 bool BandedLinearSystem<_Type>::lt(_Type value)
const {
200 problem =
"You've turned on monitoring of the sign of the determinant for a \n";
201 problem +=
"BandedLinearSystem whose elements are not of type <double>.\n";
202 throw ExceptionRuntime(problem);
206 bool BandedLinearSystem<double>::lt(
double value)
const {
210 template <
typename _Type>
211 int BandedLinearSystem<_Type>::signature(
const std::vector<int> &pivots)
const {
213 for(std::size_t i = 0; i < pivots.size(); ++i) {
214 if(pivots[ i ] - 1 !=
int(i)) {
221 template <
typename _Type>
222 void BandedLinearSystem<_Type >::backsub()
const {
223 const std::size_t L = m_pA -> noffdiag();
224 const std::size_t N = m_pB -> size();
225 (*m_pB)[ N - 1 ] /= (*m_pA)(N - 1, N - 1);
228 for(std::size_t row = N - 2; (int) row >= 0; --row) {
230 for(std::size_t col = row + 1; col < std::min(N, row + 2 * L + 1); ++col) {
231 sum += (*m_pA)(row, col) * (*m_pB)[ col ];
233 (*m_pB)[ row ] -= sum;
234 (*m_pB)[ row ] /= (*m_pA)(row, row);
238 template<
typename _Type>
243 template<
typename _Type>
Specification of the linear system class.
The collection of CppNoddy exceptions.
Some interface definitions for calling external fortran routines in LAPACK.
A spec for a collection of utility functions.
A linear system class for vector right-hand sides.
void re_solve_lapack()
Resolve the banded system.
void solve()
Solve the banded system.
void set_monitor_det(bool flag)
Store the sign of the determinant of the LHS matrix every time a solve is requested on a real system.
int get_det_sign() const
Get the sign of the determinant of the LHS matrix from the linear system just computed.
BandedLinearSystem(BandedMatrix< _Type > *Aptr, DenseVector< _Type > *Bptr, std::string which="native")
Constructor for a banded linear system object.
A matrix class that constructs a BANDED matrix.
An DenseVector class – a dense vector object.
An exception to indicate that an error has been detected in an external (LAPACK) routine.
A generic runtime exception.
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...