void PetscMatrix<T>::add_block_matrix(const DenseMatrix<T>& dm, const std::vector<numeric_index_type>& brows, const std::vector<numeric_index_type>& bcols) { libmesh_assert (this->initialized()); const numeric_index_type n_rows = dm.m(); const numeric_index_type n_cols = dm.n(); const numeric_index_type n_brows = brows.size(); const numeric_index_type n_bcols = bcols.size(); const numeric_index_type blocksize = n_rows / n_brows; libmesh_assert_equal_to (n_cols / n_bcols, blocksize); libmesh_assert_equal_to (blocksize*n_brows, n_rows); libmesh_assert_equal_to (blocksize*n_bcols, n_cols); PetscErrorCode ierr=0; #ifndef NDEBUG PetscInt petsc_blocksize; ierr = MatGetBlockSize(_mat, &petsc_blocksize); LIBMESH_CHKERRABORT(ierr); libmesh_assert_equal_to (blocksize, static_cast<numeric_index_type>(petsc_blocksize)); #endif // These casts are required for PETSc <= 2.1.5 ierr = MatSetValuesBlocked(_mat, n_brows, (PetscInt*) &brows[0], n_bcols, (PetscInt*) &bcols[0], (PetscScalar*) &dm.get_values()[0], ADD_VALUES); LIBMESH_CHKERRABORT(ierr); }
void EpetraMatrix<T>::add_matrix(const DenseMatrix<T>& dm, const std::vector<unsigned int>& rows, const std::vector<unsigned int>& cols) { libmesh_assert (this->initialized()); const unsigned int m = dm.m(); const unsigned int n = dm.n(); libmesh_assert (rows.size() == m); libmesh_assert (cols.size() == n); _mat->SumIntoGlobalValues(m, (int *)&rows[0], n, (int *)&cols[0], &dm.get_values()[0]); }
void EpetraMatrix<T>::add_matrix(const DenseMatrix<T>& dm, const std::vector<numeric_index_type>& rows, const std::vector<numeric_index_type>& cols) { libmesh_assert (this->initialized()); const numeric_index_type m = dm.m(); const numeric_index_type n = dm.n(); libmesh_assert_equal_to (rows.size(), m); libmesh_assert_equal_to (cols.size(), n); _mat->SumIntoGlobalValues(m, (int *)&rows[0], n, (int *)&cols[0], &dm.get_values()[0]); }
void PetscMatrix<T>::add_matrix(const DenseMatrix<T>& dm, const std::vector<numeric_index_type>& rows, const std::vector<numeric_index_type>& cols) { libmesh_assert (this->initialized()); const numeric_index_type n_rows = dm.m(); const numeric_index_type n_cols = dm.n(); libmesh_assert_equal_to (rows.size(), n_rows); libmesh_assert_equal_to (cols.size(), n_cols); PetscErrorCode ierr=0; // These casts are required for PETSc <= 2.1.5 ierr = MatSetValues(_mat, n_rows, (PetscInt*) &rows[0], n_cols, (PetscInt*) &cols[0], (PetscScalar*) &dm.get_values()[0], ADD_VALUES); LIBMESH_CHKERRABORT(ierr); }
void DenseMatrix<T>::_svd_lapack (DenseVector<Real> & sigma, DenseMatrix<Number> & U, DenseMatrix<Number> & VT) { // The calling sequence for dgetrf is: // DGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, INFO ) // JOBU (input) CHARACTER*1 // Specifies options for computing all or part of the matrix U: // = 'A': all M columns of U are returned in array U: // = 'S': the first min(m,n) columns of U (the left singular // vectors) are returned in the array U; // = 'O': the first min(m,n) columns of U (the left singular // vectors) are overwritten on the array A; // = 'N': no columns of U (no left singular vectors) are // computed. char JOBU = 'S'; // JOBVT (input) CHARACTER*1 // Specifies options for computing all or part of the matrix // V**T: // = 'A': all N rows of V**T are returned in the array VT; // = 'S': the first min(m,n) rows of V**T (the right singular // vectors) are returned in the array VT; // = 'O': the first min(m,n) rows of V**T (the right singular // vectors) are overwritten on the array A; // = 'N': no rows of V**T (no right singular vectors) are // computed. char JOBVT = 'S'; // Note: Lapack is going to compute the singular values of A^T. If // A=U * S * V^T, then A^T = V * S * U^T, which means that the // values returned in the "U_val" array actually correspond to the // entries of the V matrix, and the values returned in the VT_val // array actually correspond to the entries of U^T. Therefore, we // pass VT in the place of U and U in the place of VT below! std::vector<Real> sigma_val; int M = this->n(); int N = this->m(); int min_MN = (M < N) ? M : N; // Size user-provided storage appropriately. Inside svd_helper: // U_val is sized to (M x min_MN) // VT_val is sized to (min_MN x N) // So, we set up U to have the shape of "VT_val^T", and VT to // have the shape of "U_val^T". // // Finally, since the results are stored in column-major order by // Lapack, but we actually want the transpose of what Lapack // returns, this means (conveniently) that we don't even have to // copy anything after the call to _svd_helper, it should already be // in the correct order! U.resize(N, min_MN); VT.resize(min_MN, M); _svd_helper(JOBU, JOBVT, sigma_val, VT.get_values(), U.get_values()); // Copy the singular values into sigma. sigma.resize(cast_int<unsigned int>(sigma_val.size())); for (unsigned int i=0; i<sigma.size(); i++) sigma(i) = sigma_val[i]; }