21 #include "libmesh/dof_map.h"
22 #include "libmesh/dense_matrix.h"
23 #include "libmesh/diagonal_matrix.h"
24 #include "libmesh/laspack_matrix.h"
25 #include "libmesh/eigen_sparse_matrix.h"
26 #include "libmesh/parallel.h"
27 #include "libmesh/petsc_matrix.h"
28 #include "libmesh/sparse_matrix.h"
29 #include "libmesh/trilinos_epetra_matrix.h"
30 #include "libmesh/numeric_vector.h"
31 #include "libmesh/enum_solver_package.h"
49 ParallelObject(comm_in),
78 const std::vector<numeric_index_type> & brows,
79 const std::vector<numeric_index_type> & bcols)
81 libmesh_assert_equal_to (dm.
m() / brows.size(), dm.
n() / bcols.size());
84 (dm.
m() / brows.size());
86 libmesh_assert_equal_to (dm.
m()%blocksize, 0);
87 libmesh_assert_equal_to (dm.
n()%blocksize, 0);
89 std::vector<numeric_index_type> rows, cols;
91 rows.reserve(blocksize*brows.size());
92 cols.reserve(blocksize*bcols.size());
94 for (
auto & row : brows)
98 for (
unsigned int v=0; v<blocksize; v++)
102 for (
auto & col : bcols)
106 for (
unsigned int v=0; v<blocksize; v++)
110 this->add_matrix (dm, rows, cols);
123 libmesh_not_implemented();
126 os <<
"Real part:" << std::endl;
127 for (
auto i : make_range(this->m()))
129 for (
auto j : make_range(this->n()))
130 os << std::setw(8) << (*this)(i,j).
real() <<
" ";
134 os << std::endl <<
"Imaginary part:" << std::endl;
135 for (
auto i : make_range(this->m()))
137 for (
auto j : make_range(this->n()))
138 os << std::setw(8) << (*this)(i,j).
imag() <<
" ";
149 template <
typename T>
150 std::unique_ptr<SparseMatrix<T>>
152 const SolverPackage solver_package,
153 const MatrixBuildType matrix_build_type )
158 if (matrix_build_type == MatrixBuildType::DIAGONAL)
159 return std::make_unique<DiagonalMatrix<T>>(comm);
162 switch (solver_package)
165 #ifdef LIBMESH_HAVE_LASPACK
167 return std::make_unique<LaspackMatrix<T>>(comm);
171 #ifdef LIBMESH_HAVE_PETSC
173 return std::make_unique<PetscMatrix<T>>(comm);
177 #ifdef LIBMESH_TRILINOS_HAVE_EPETRA
179 return std::make_unique<EpetraMatrix<T>>(comm);
183 #ifdef LIBMESH_HAVE_EIGEN
185 return std::make_unique<EigenSparseMatrix<T>>(comm);
189 libmesh_error_msg(
"ERROR: Unrecognized solver package: " << solver_package);
194 template <
typename T>
199 this->vector_mult_add(dest,arg);
204 template <
typename T>
215 template <
typename T>
219 libmesh_not_implemented();
224 template <
typename T>
227 parallel_object_only();
231 libmesh_error_msg_if(!this->_dof_map,
"Error! Trying to print a matrix with no dof_map set!");
235 if (this->processor_id() == 0)
237 libmesh_assert_equal_to (this->_dof_map->first_dof(), 0);
239 i!=this->_dof_map->end_dof(); ++i)
243 for (
auto j : make_range(this->n()))
246 if (c != static_cast<T>(0.0))
248 os << i <<
" " << j <<
" " << c << std::endl;
254 for (
auto j : make_range(this->n()))
255 os << (*this)(i,j) <<
" ";
260 std::vector<numeric_index_type> ibuf, jbuf;
263 for (
auto p : IntRange<processor_id_type>(1, this->n_processors()))
265 this->comm().receive(p, ibuf);
266 this->comm().receive(p, jbuf);
267 this->comm().receive(p, cbuf);
268 libmesh_assert_equal_to (ibuf.size(), jbuf.size());
269 libmesh_assert_equal_to (ibuf.size(), cbuf.size());
273 libmesh_assert_greater_equal (ibuf.front(), currenti);
274 libmesh_assert_greater_equal (ibuf.back(), ibuf.front());
276 std::size_t currentb = 0;
277 for (;currenti <= ibuf.back(); ++currenti)
283 if (currentb < ibuf.size() &&
284 ibuf[currentb] == currenti &&
287 os << currenti <<
" " << j <<
" " << cbuf[currentb] << std::endl;
294 for (
auto j : make_range(this->n()))
296 if (currentb < ibuf.size() &&
297 ibuf[currentb] == currenti &&
300 os << cbuf[currentb] <<
" ";
304 os << static_cast<T>(0.0) <<
" ";
312 for (; currenti != this->m(); ++currenti)
315 os << static_cast<T>(0.0) <<
" ";
322 std::vector<numeric_index_type> ibuf, jbuf;
328 i!=this->_dof_map->end_dof(); ++i)
330 for (
auto j : make_range(this->n()))
333 if (c != static_cast<T>(0.0))
341 this->comm().send(0,ibuf);
342 this->comm().send(0,jbuf);
343 this->comm().send(0,cbuf);
virtual void add_block_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &brows, const std::vector< numeric_index_type > &bcols)
将完整矩阵 dm 添加到 SparseMatrix。这对于在装配时添加元素矩阵很有用。 矩阵被假定为块矩阵,brow、bcol 对应于*块*行和列索引。
SparseMatrix(const Parallel::Communicator &comm)
构造函数;初始化矩阵为空,没有任何结构,即矩阵无法使用。
unsigned int n() const
返回矩阵的列维度。
This helper class can be called on multiple threads to compute the sparsity pattern (or graph) of the...
boost::multiprecision::float128 real(const boost::multiprecision::float128 in)
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
计算 ,其中 v 是一个指针, 每个 dof_indices[i] 指定了要添加的值 v[i] 的位置。 这应该在子类中进行重写以提高效率。请注意,此方法的库实现是线程安全的。 ...
void vector_mult(NumericVector< T > &dest, const NumericVector< T > &arg) const
将矩阵乘以 NumericVector arg 并将结果存储在 NumericVector dest 中。
void attach_sparsity_pattern(const SparsityPattern::Build &sp)
设置要使用的稀疏性模式的指针。在矩阵需要比系统中的大(或更小以提高效率)的模式, 或者在 DofMap 未计算系统稀疏性模式的情况下使用。
void vector_mult_add(NumericVector< T > &dest, const NumericVector< T > &arg) const
将矩阵乘以 NumericVector arg ,并将结果添加到 NumericVector dest 中。
static std::unique_ptr< SparseMatrix< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package(), const MatrixBuildType matrix_build_type=MatrixBuildType::AUTOMATIC)
使用由 solver_package 指定的线性求解器包构建一个 SparseMatrix<T>。
virtual void zero()=0
将所有条目设置为零。等同于 v = 0,但更明显且更快。
这是一个通用的稀疏矩阵类。该类包含了必须在派生类中覆盖的纯虚拟成员。 使用一个公共的基类允许从不同的求解器包中以不同的格式统一访问稀疏矩阵。
This class handles the numbering of degrees of freedom on a mesh.
void libmesh_ignore(const Args &...)
dof_id_type numeric_index_type
bool _is_initialized
Flag that tells if init() has been called.
unsigned int m() const
返回矩阵的行维度。
const SparsityPattern::Build * get_sparsity_pattern() const
virtual void zero_rows(std::vector< numeric_index_type > &rows, T diag_value=0.0)
将所有行条目设置为 0,然后将 diag_value 放在对角线条目。
void attach_dof_map(const DofMap &dof_map)
设置要使用的 DofMap 的指针。如果不使用单独的稀疏性模式, 则使用来自 DofMap 的模式。
void print(std::ostream &os=libMesh::out, const bool sparse=false) const
将矩阵的内容以统一的样式打印到屏幕上,而不考虑正在使用的矩阵/求解器包。
bool initialized()
Checks that library initialization has been done.
boost::multiprecision::float128 imag(const boost::multiprecision::float128)
定义用于有限元类型计算的密集矩阵。 用于在求和成全局矩阵之前存储单元刚度矩阵。所有被覆盖的虚函数都记录在dense_matrix_base.h中。