void LaspackMatrix<T>::update_sparsity_pattern (const SparsityPattern::Graph &sparsity_pattern) { // clear data, start over this->clear (); // big trouble if this fails! libmesh_assert(this->_dof_map); const numeric_index_type n_rows = sparsity_pattern.size(); // Initialize the _row_start data structure, // allocate storage for the _csr array { std::size_t size = 0; for (numeric_index_type row=0; row<n_rows; row++) size += sparsity_pattern[row].size(); _csr.resize (size); _row_start.reserve(n_rows + 1); } // Initize the _csr data structure. { std::vector<numeric_index_type>::iterator pos = _csr.begin(); _row_start.push_back (pos); for (numeric_index_type row=0; row<n_rows; row++) { // insert the row indices for (SparsityPattern::Row::const_iterator col = sparsity_pattern[row].begin(); col != sparsity_pattern[row].end(); ++col) { libmesh_assert (pos != _csr.end()); *pos = *col; ++pos; } _row_start.push_back (pos); } } // Initialize the matrix libmesh_assert (!this->initialized()); this->init (); libmesh_assert (this->initialized()); //libMesh::out << "n_rows=" << n_rows << std::endl; //libMesh::out << "m()=" << m() << std::endl; libmesh_assert_equal_to (n_rows, this->m()); // Tell the matrix about its structure. Initialize it // to zero. for (numeric_index_type i=0; i<n_rows; i++) { const std::vector<numeric_index_type>::const_iterator rs = _row_start[i]; const numeric_index_type length = _row_start[i+1] - rs; Q_SetLen (&_QMat, i+1, length); for (numeric_index_type l=0; l<length; l++) { const numeric_index_type j = *(rs+l); // sanity check //libMesh::out << "m()=" << m() << std::endl; //libMesh::out << "(i,j,l) = (" << i // << "," << j // << "," << l // << ")" << std::endl; //libMesh::out << "pos(i,j)=" << pos(i,j) // << std::endl; libmesh_assert_equal_to (this->pos(i,j), l); Q_SetEntry (&_QMat, i+1, l, j+1, 0.); } } // That's it! //libmesh_here(); }
void EpetraMatrix<T>::update_sparsity_pattern (const SparsityPattern::Graph &sparsity_pattern) { // clear data, start over this->clear (); // big trouble if this fails! libmesh_assert (this->_dof_map != NULL); const unsigned int n_rows = sparsity_pattern.size(); const unsigned int m = this->_dof_map->n_dofs(); const unsigned int n = m; const unsigned int n_l = this->_dof_map->n_dofs_on_processor(libMesh::processor_id()); const unsigned int m_l = n_l; // error checking #ifndef NDEBUG { libmesh_assert (n == m); libmesh_assert (n_l == m_l); unsigned int summed_m_l = m_l, summed_n_l = n_l; Parallel::sum (summed_m_l); Parallel::sum (summed_n_l); libmesh_assert (m == summed_m_l); libmesh_assert (n == summed_n_l); } #endif // build a map defining the data distribution _map = new Epetra_Map (m, m_l, 0, Epetra_MpiComm (libMesh::COMM_WORLD)); libmesh_assert (static_cast<unsigned int>(_map->NumGlobalPoints()) == m); libmesh_assert (static_cast<unsigned int>(_map->MaxAllGID()+1) == m); const std::vector<unsigned int>& n_nz = this->_dof_map->get_n_nz(); const std::vector<unsigned int>& n_oz = this->_dof_map->get_n_oz(); // Make sure the sparsity pattern isn't empty libmesh_assert (n_nz.size() == n_l); libmesh_assert (n_oz.size() == n_l); // Epetra wants the total number of nonzeros, both local and remote. std::vector<int> n_nz_tot; /**/ n_nz_tot.reserve(n_nz.size()); for (unsigned int i=0; i<n_nz.size(); i++) n_nz_tot.push_back(std::min(n_nz[i] + n_oz[i], n)); if (m==0) return; _graph = new Epetra_CrsGraph(Copy, *_map, &n_nz_tot[0]); // Tell the matrix about its structure. Initialize it // to zero. for (unsigned int i=0; i<n_rows; i++) _graph->InsertGlobalIndices(_graph->GRID(i), sparsity_pattern[i].size(), const_cast<int *>((const int *)&sparsity_pattern[i][0])); _graph->FillComplete(); //Initialize the matrix libmesh_assert (!this->initialized()); this->init (); libmesh_assert (this->initialized()); }