ViennaSHE 1.3.0
Free open-source semiconductor device simulator using spherical harmonics expansions techniques.
block_matrix_writer.hpp
Go to the documentation of this file.
1#ifndef VIENNASHE_UTIL_BLOCK_MATRIX_WRITER_HPP
2#define VIENNASHE_UTIL_BLOCK_MATRIX_WRITER_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#include <cassert>
19
20// viennashe
23
28namespace viennashe
29{
30 namespace util
31 {
32
44 template <typename SystemMatrixType,
45 typename BlockMatrixType,
46 typename RowIndexIterator,
47 typename ColumnIndexIterator>
48 void add_block_matrix(SystemMatrixType & system_matrix,
49 std::size_t row_index, std::size_t col_index,
50 double prefactor,
51 BlockMatrixType const & coupling_matrix,
52 RowIndexIterator row_iter,
53 ColumnIndexIterator const & col_iter_init,
54 bool elastic_scattering_roundoff_error_prevention = false)
55 {
56 //iterate over harmonics in row and column direction
57
58 assert(prefactor == prefactor && bool("Writing nan to matrix!"));
59
60 std::size_t row = row_index;
61 for (; row_iter.valid(); ++row_iter, ++row)
62 {
63 assert( *row_iter < static_cast<long>(coupling_matrix.size1() ));
64 std::size_t col = col_index;
65
66 for (ColumnIndexIterator col_iter(col_iter_init);
67 col_iter.valid();
68 ++col_iter, ++col)
69 {
70 assert( *col_iter < static_cast<long>(coupling_matrix.size2() ));
71 double entry = coupling_matrix(std::size_t(*row_iter), std::size_t(*col_iter));
72
73 if (entry) //preserve sparsity structure of coupling matrices. Double-inequality to avoid warnings regarding equality to zero
74 {
75 if (elastic_scattering_roundoff_error_prevention && row == row_index && col == col_index) // avoid round-off errors for scattering mechanisms
76 continue;
77 system_matrix(row, col) += prefactor * entry;
78 }
79 }
80 }
81 }
82
83
96 template <typename SystemMatrixType,
97 typename BlockMatrixType,
98 typename RowIndexIterator,
99 typename ColumnIndexIterator,
100 typename FoldVectorType>
101 void add_folded_block_matrix(SystemMatrixType & system_matrix,
102 long row_index, long col_index,
103 double prefactor,
104 BlockMatrixType const & coupling_matrix,
105 RowIndexIterator row_iter,
106 ColumnIndexIterator const & col_iter_init,
107 FoldVectorType const & fold_vector, long fold_index_start
108 )
109 {
110 //iterate over harmonics in row and column direction
111 assert(row_index >= 0 && "Row index must be non-negative!");
112 assert(col_index >= 0 && "Col index must be non-negative!");
113
114 assert(prefactor == prefactor && bool("Writing nan to matrix!"));
115
116 long row = row_index;
117 for (; row_iter.valid(); ++row_iter)
118 {
119 assert( *row_iter < static_cast<long>(coupling_matrix.size1()) );
120
121 double folded_val = 0;
122 std::size_t inner_iters = 0;
123 for (ColumnIndexIterator col_iter(col_iter_init);
124 col_iter.valid();
125 ++col_iter, ++inner_iters)
126 {
127 assert( *col_iter < static_cast<long>(coupling_matrix.size2()) );
128 folded_val += coupling_matrix(*row_iter, *col_iter) * fold_vector[fold_index_start + inner_iters];
129 }
130
131 if (folded_val) //preserve sparsity structure of coupling matrices. Double-inequality to avoid warnings regarding equality to zero
132 system_matrix(row, col_index) += prefactor * folded_val;
133
134 ++row;
135 }
136 }
137
138
149 template <typename VectorType,
150 typename BlockMatrixType,
151 typename RowIndexIterator,
152 typename ColumnIndexIterator>
153 void subtract_folded_block_vector(VectorType & residual,
154 std::size_t row_index,
155 double prefactor,
156 BlockMatrixType const & coupling_matrix,
157 RowIndexIterator row_iter,
158 ColumnIndexIterator const & col_iter_init,
159 double const * fold_vector)
160 {
161 assert(prefactor == prefactor && bool("Writing nan to vector!"));
162
163 //iterate over harmonics in row and column direction
164
165 std::size_t row = row_index;
166 for (; row_iter.valid(); ++row_iter)
167 {
168 assert( *row_iter < static_cast<long>(coupling_matrix.size1() ));
169
170 double folded_val = 0;
171 std::size_t inner_iters = 0;
172 for (ColumnIndexIterator col_iter(col_iter_init);
173 col_iter.valid();
174 ++col_iter, ++inner_iters)
175 {
176 assert( *col_iter < static_cast<long>(coupling_matrix.size2() ));
177 folded_val += coupling_matrix(std::size_t(*row_iter), std::size_t(*col_iter)) * fold_vector[inner_iters];
178 }
179
180 if (folded_val) //preserve sparsity structure of coupling matrices. Double-inequality to avoid warnings regarding equality to zero
181 residual[row] -= prefactor * folded_val;
182
183 ++row;
184 }
185 }
186
187 } //namespace util
188} //namespace viennashe
189
190#endif
void add_folded_block_matrix(SystemMatrixType &system_matrix, long row_index, long col_index, double prefactor, BlockMatrixType const &coupling_matrix, RowIndexIterator row_iter, ColumnIndexIterator const &col_iter_init, FoldVectorType const &fold_vector, long fold_index_start)
Writes a sub-matrix of a block matrix 'coupling_matrix' into the global system matrix,...
void add_block_matrix(SystemMatrixType &system_matrix, std::size_t row_index, std::size_t col_index, double prefactor, BlockMatrixType const &coupling_matrix, RowIndexIterator row_iter, ColumnIndexIterator const &col_iter_init, bool elastic_scattering_roundoff_error_prevention=false)
Writes a sub-matrix of a block matrix 'coupling_matrix' into the global system matrix,...
void subtract_folded_block_vector(VectorType &residual, std::size_t row_index, double prefactor, BlockMatrixType const &coupling_matrix, RowIndexIterator row_iter, ColumnIndexIterator const &col_iter_init, double const *fold_vector)
Writes a sub-matrix of a block matrix 'coupling_matrix' to the residual vector. The columns are 'fold...
The main ViennaSHE namespace. All functionality resides inside this namespace.
Definition: accessors.hpp:40
Provides a number of fundamental constants. All constants in SI units.
Implementation of spherical harmonics plus helper functions.