ViennaSHE 1.3.0
Free open-source semiconductor device simulator using spherical harmonics expansions techniques.
dense_linear_solver.hpp
Go to the documentation of this file.
1#ifndef VIENNASHE_SOLVERS_NATIVE_DENSE_LINEAR_SOLVER_HPP
2#define VIENNASHE_SOLVERS_NATIVE_DENSE_LINEAR_SOLVER_HPP
3
4/* ============================================================================
5 Copyright (c) 2011-2022, Institute for Microelectronics,
6 Institute for Analysis and Scientific Computing,
7 TU Wien.
8
9 -----------------
10 ViennaSHE - The Vienna Spherical Harmonics Expansion Boltzmann Solver
11 -----------------
12
13 http://viennashe.sourceforge.net/
14
15 License: MIT (X11), see file LICENSE in the base directory
16=============================================================================== */
17
18// viennashe
21#include "viennashe/log/log.hpp"
24
25
31namespace viennashe
32{
33 namespace solvers
34 {
35
36 namespace detail
37 {
38 // pivoting strategy: Pick element of B(:,j) below diagonal with largest modulus
39 template <typename NumericT, typename VectorType>
41 VectorType & c,
42 std::vector<std::size_t> pivot_vector,
43 std::size_t current_row)
44 {
45 // find pivot row:
46 std::size_t pivot_row = current_row;
47 NumericT pivot_element = B(current_row, current_row);
48
49 for (std::size_t i=current_row; i<B.size1(); ++i)
50 {
51 double element = B(i, current_row);
52 if (std::fabs(element) > std::fabs(pivot_element))
53 {
54 pivot_row = i;
55 pivot_element = element;
56 }
57 }
58
59 // swap rows:
60 if (pivot_row > current_row)
61 {
62 std::swap(pivot_vector[pivot_row], pivot_vector[current_row]);
63 std::swap(c[pivot_row], c[current_row]);
64 for (std::size_t j=0; j<B.size2(); ++j)
65 std::swap(B(pivot_row, j), B(current_row, j));
66 }
67 }
68 }
69
76 template <typename NumericT, typename VectorType>
78 VectorType const & b,
81 {
82 (void)config; //Silence unused parameter warnings
83 log::info<log_linear_solver>() << "* solve(): Solving system (Gauss solver, single-threaded)... " << std::endl;
84
85 // copy A and b to work system Bx = c
87 VectorType c(b);
88 std::vector<std::size_t> pivot_vector(B.size1());
89
90 for (std::size_t i=0; i<pivot_vector.size(); ++i)
91 pivot_vector[i] = i;
92
93 //
94 // Phase 1: Eliminate lower-triangular entries to obtain upper triangular matrix:
95 //
96 for (std::size_t i=0; i<B.size1(); ++i)
97 {
98 // pivot if necessary:
99 detail::pivot_matrix(B, c, pivot_vector, i);
100
101 if (!B(i,i))
102 throw std::runtime_error("Provided matrix is singular!");
103
104 // eliminate column entries below diagonal
105 for (std::size_t elim_row = i+1; elim_row < B.size1(); ++elim_row)
106 {
107 NumericT factor = B(elim_row, i) / B(i,i);
108 c[elim_row] -= c[i] * factor;
109 for (std::size_t j=i; j<B.size2(); ++j)
110 B(elim_row, j) -= B(i, j) * factor;
111 }
112 }
113
114 //
115 // Phase 2: Substitute:
116 //
117 for (std::size_t i=0; i < B.size1(); ++i)
118 {
119 std::size_t row = B.size1() - (i+1);
120 for (std::size_t j=row+1; j<B.size2(); ++j)
121 c[row] -= B(row, j) * c[j];
122 c[row] /= B(row, row);
123 }
124
125 //
126 // Phase 3: Form actual solution vector by inverting the pivoting:
127 //
128 VectorType result(c.size());
129 for (std::size_t i=0; i<result.size(); ++i)
130 result[pivot_vector[i]] = c[i];
131
132 return result;
133 }
134
135
137 template <typename NumericT,
138 typename VectorType>
140 VectorType const & b,
143 {
144 // convert to dense matrix and solve
146
147 for (std::size_t i = 0;
148 i != A.size1();
149 ++i)
150 {
151 typedef typename viennashe::math::sparse_matrix<NumericT>::const_iterator2 AlongRowIterator;
153
154 RowType const & row_i = A.row(i);
155
156 for (AlongRowIterator col_it = row_i.begin();
157 col_it != row_i.end();
158 ++col_it)
159 {
160 A_dense(i, col_it->first) = col_it->second;
161 }
162 }
163
165 }
166
167 } // namespace solvers
168} // namespace viennashe
169
170
171#endif
Defines a set of checker functors for micro-tests within ViennaSHE.
The main SHE configuration class. To be adjusted by the user for his/her needs.
Definition: config.hpp:124
Sparse matrix class based on a vector of binary trees for holding the entries.
Definition: linalg_util.hpp:69
MapType const & row(size_t i) const
MapType::const_iterator const_iterator2
Definition: linalg_util.hpp:82
Internal tag used for the specification of a dense linear solver (Gauss, single-threaded)
Definition: forwards.h:203
A configuration class holding options for use within the different linear solvers.
Definition: config.hpp:57
Implementation of various utilities related to linear algebra.
A logging facility providing fine-grained control over logging in ViennaSHE.
void pivot_matrix(viennashe::math::dense_matrix< NumericT > &B, VectorType &c, std::vector< std::size_t > pivot_vector, std::size_t current_row)
std::vector< double > solve(viennashe::math::sparse_matrix< double > &A, std::vector< double > const &b, linear_solver_config const &config)
Public interface for solving a system of linear equations represented using a sparse matrix.
The main ViennaSHE namespace. All functionality resides inside this namespace.
Definition: accessors.hpp:40
The SHE configuration class is defined here.
Defines all the log keys used within the viennashe::solvers namespace.