//======================================================= int EpetraExt_HypreIJMatrix::RightScale(const Epetra_Vector& X) { // First we need to import off-processor values of the vector Epetra_Import Importer(RowMatrixColMap(), RowMatrixRowMap()); Epetra_Vector Import_Vector(RowMatrixColMap(), true); EPETRA_CHK_ERR(Import_Vector.Import(X, Importer, Insert, 0)); for(int i = 0; i < NumMyRows_; i++){ //Vector-scalar mult on ith column int num_entries; double *values; int *indices; // Get values and indices of ith row of matrix EPETRA_CHK_ERR(HYPRE_ParCSRMatrixGetRow(ParMatrix_,i+MyRowStart_, &num_entries, &indices, &values)); EPETRA_CHK_ERR(HYPRE_ParCSRMatrixRestoreRow(ParMatrix_,i+MyRowStart_,&num_entries,&indices,&values)); Teuchos::Array<int> new_indices; new_indices.resize(num_entries); Teuchos::Array<double> new_values; new_values.resize(num_entries); for(int j = 0; j < num_entries; j++){ // Multiply column j with jth element int index = RowMatrixColMap().LID(indices[j]); TEUCHOS_TEST_FOR_EXCEPTION(index < 0, std::logic_error, "Index is negtive."); new_values[j] = values[j] * Import_Vector[index]; new_indices[j] = indices[j]; } // Finally set values of the Matrix for this row int rows[1]; rows[0] = i+MyRowStart_; EPETRA_CHK_ERR(HYPRE_IJMatrixSetValues(Matrix_, 1, &num_entries, rows, &new_indices[0], &new_values[0])); } HaveNumericConstants_ = false; UpdateFlops(NumGlobalNonzeros()); return 0; } //RightScale()
int32_t impl_bHYPRE_IJParCSRMatrix_SetValues( /* in */ bHYPRE_IJParCSRMatrix self, /* in */ int32_t nrows, /* in rarray[nrows] */ int32_t* ncols, /* in rarray[nrows] */ int32_t* rows, /* in rarray[nnonzeros] */ int32_t* cols, /* in rarray[nnonzeros] */ double* values, /* in */ int32_t nnonzeros, /* out */ sidl_BaseInterface *_ex) { *_ex = 0; { /* DO-NOT-DELETE splicer.begin(bHYPRE.IJParCSRMatrix.SetValues) */ /* Insert the implementation of the SetValues method here... */ int ierr=0; struct bHYPRE_IJParCSRMatrix__data * data; HYPRE_IJMatrix ij_A; data = bHYPRE_IJParCSRMatrix__get_data( self ); ij_A = data -> ij_A; ierr = HYPRE_IJMatrixSetValues( ij_A, nrows, ncols, rows, cols, values ); return( ierr ); /* DO-NOT-DELETE splicer.end(bHYPRE.IJParCSRMatrix.SetValues) */ } }
HYPRE_Int hypre_ParaSailsBuildIJMatrix(hypre_ParaSails obj, HYPRE_IJMatrix *pij_A) { hypre_ParaSails_struct *internal = (hypre_ParaSails_struct *) obj; ParaSails *ps = internal->ps; Matrix *mat = internal->ps->M; HYPRE_Int *diag_sizes, *offdiag_sizes, local_row, i, j; HYPRE_Int size; HYPRE_Int *col_inds; HYPRE_Real *values; HYPRE_IJMatrixCreate( ps->comm, ps->beg_row, ps->end_row, ps->beg_row, ps->end_row, pij_A ); HYPRE_IJMatrixSetObjectType( *pij_A, HYPRE_PARCSR ); diag_sizes = hypre_CTAlloc(HYPRE_Int, ps->end_row - ps->beg_row + 1); offdiag_sizes = hypre_CTAlloc(HYPRE_Int, ps->end_row - ps->beg_row + 1); local_row = 0; for (i=ps->beg_row; i<= ps->end_row; i++) { MatrixGetRow(mat, local_row, &size, &col_inds, &values); NumberingLocalToGlobal(ps->numb, size, col_inds, col_inds); for (j=0; j < size; j++) { if (col_inds[j] < ps->beg_row || col_inds[j] > ps->end_row) offdiag_sizes[local_row]++; else diag_sizes[local_row]++; } local_row++; } HYPRE_IJMatrixSetDiagOffdSizes( *pij_A, (const HYPRE_Int *) diag_sizes, (const HYPRE_Int *) offdiag_sizes ); hypre_TFree(diag_sizes); hypre_TFree(offdiag_sizes); HYPRE_IJMatrixInitialize( *pij_A ); local_row = 0; for (i=ps->beg_row; i<= ps->end_row; i++) { MatrixGetRow(mat, local_row, &size, &col_inds, &values); HYPRE_IJMatrixSetValues( *pij_A, 1, &size, &i, (const HYPRE_Int *) col_inds, (const HYPRE_Real *) values ); NumberingGlobalToLocal(ps->numb, size, col_inds, col_inds); local_row++; } HYPRE_IJMatrixAssemble( *pij_A ); return hypre_error_flag; }
void HypreSolver2D::build_A() { HYPRE_IJMatrixCreate(MPI_COMM_WORLD, ilower, iupper, ilower, iupper, &A); HYPRE_IJMatrixSetObjectType(A, HYPRE_PARCSR); HYPRE_IJMatrixInitialize(A); int nnz; double values[5]; int cols[5]; for(int i=ilower; i<=iupper; i++) { nnz = 0; // North if ((i-N1)>=0) { cols[nnz] = i-N1; values[nnz] = -1.0; nnz++; } // Left if (i%N1) { cols[nnz] = i-1; values[nnz] = -1.0; nnz++; } // Center cols[nnz] = i; values[nnz] = 4.0; nnz++; // Right if ((i+1)%N1) { cols[nnz] = i+1; values[nnz] = -1.0; nnz++; } // South if ((i+N1)<N) { cols[nnz] = i+N1; values[nnz] = -1.0; nnz++; } HYPRE_IJMatrixSetValues(A, 1, &nnz, &i, cols, values); } HYPRE_IJMatrixAssemble(A); HYPRE_IJMatrixGetObject(A, (void**) &parcsr_A); }
HYPRE_Int HYPRE_IJMatrixRead( const char *filename, MPI_Comm comm, HYPRE_Int type, HYPRE_IJMatrix *matrix_ptr ) { HYPRE_IJMatrix matrix; HYPRE_Int ilower, iupper, jlower, jupper; HYPRE_Int ncols, I, J; HYPRE_Complex value; HYPRE_Int myid, ret; char new_filename[255]; FILE *file; hypre_MPI_Comm_rank(comm, &myid); hypre_sprintf(new_filename,"%s.%05d", filename, myid); if ((file = fopen(new_filename, "r")) == NULL) { hypre_error_in_arg(1); return hypre_error_flag; } hypre_fscanf(file, "%d %d %d %d", &ilower, &iupper, &jlower, &jupper); HYPRE_IJMatrixCreate(comm, ilower, iupper, jlower, jupper, &matrix); HYPRE_IJMatrixSetObjectType(matrix, type); HYPRE_IJMatrixInitialize(matrix); /* It is important to ensure that whitespace follows the index value to help * catch mistakes in the input file. See comments in IJVectorRead(). */ ncols = 1; while ( (ret = hypre_fscanf(file, "%d %d%*[ \t]%le", &I, &J, &value)) != EOF ) { if (ret != 3) { hypre_error_w_msg(HYPRE_ERROR_GENERIC, "Error in IJ matrix input file."); return hypre_error_flag; } if (I < ilower || I > iupper) HYPRE_IJMatrixAddToValues(matrix, 1, &ncols, &I, &J, &value); else HYPRE_IJMatrixSetValues(matrix, 1, &ncols, &I, &J, &value); } HYPRE_IJMatrixAssemble(matrix); fclose(file); *matrix_ptr = matrix; return hypre_error_flag; }
static void setup_hypre_mat(MAT *A, HYPRE_IJMatrix *pa) { MAT_ROW *row; INT i, j, d, I, n0, n, *cols; assert(sizeof(INT) == sizeof(int) && sizeof(FLOAT)==sizeof(double)); phgMatUnpack(A); HYPRE_IJMatrixCreate(A->rmap->comm, A->rmap->partition[A->rmap->rank], A->rmap->partition[A->rmap->rank + 1] - 1, A->cmap->partition[A->cmap->rank], A->cmap->partition[A->cmap->rank + 1] - 1, pa); HYPRE_IJMatrixSetObjectType(*pa, HYPRE_PARCSR); HYPRE_IJMatrixInitialize(*pa); I = A->rmap->partition[A->rmap->rank]; n0 = A->cmap->partition[A->cmap->rank]; n = 0; cols = NULL; for (i = 0, row = A->rows; i < A->rmap->nlocal; i++, row++, I++) { if (row->ncols > 0) { if (n < row->ncols) { phgFree(cols); cols = phgAlloc((n = row->ncols) * sizeof(*cols)); } for (j = 0; j < row->ncols; j++) { if ((d = row->cols[j]) < A->cmap->nlocal) cols[j] = d + n0; else cols[j] = A->O2Gmap[d - A->cmap->nlocal]; } HYPRE_IJMatrixSetValues(*pa, 1, &row->ncols, &I, cols, row->data); } } phgFree(cols); HYPRE_IJMatrixAssemble(*pa); }
//======================================================= int EpetraExt_HypreIJMatrix::LeftScale(const Epetra_Vector& X) { for(int i = 0; i < NumMyRows_; i++){ //Vector-scalar mult on ith row int num_entries; int *indices; double *values; EPETRA_CHK_ERR(HYPRE_ParCSRMatrixGetRow(ParMatrix_,i+MyRowStart_, &num_entries, &indices, &values)); EPETRA_CHK_ERR(HYPRE_ParCSRMatrixRestoreRow(ParMatrix_,i+MyRowStart_, &num_entries, &indices, &values)); Teuchos::Array<double> new_values; new_values.resize(num_entries); Teuchos::Array<int> new_indices; new_indices.resize(num_entries); for(int j = 0; j < num_entries; j++){ // Scale this row with the appropriate values from the vector new_values[j] = X[i]*values[j]; new_indices[j] = indices[j]; } int rows[1]; rows[0] = i+MyRowStart_; EPETRA_CHK_ERR(HYPRE_IJMatrixSetValues(Matrix_, 1, &num_entries, rows, &new_indices[0], &new_values[0])); // Finally set values of the Matrix for this row } HaveNumericConstants_ = false; UpdateFlops(NumGlobalNonzeros()); return 0; } //LeftScale()
int hypre_SStructUMatrixSetBoxValues( hypre_SStructMatrix *matrix, int part, hypre_Index ilower, hypre_Index iupper, int var, int nentries, int *entries, double *values, int add_to ) { HYPRE_IJMatrix ijmatrix = hypre_SStructMatrixIJMatrix(matrix); hypre_SStructGraph *graph = hypre_SStructMatrixGraph(matrix); hypre_SStructGrid *grid = hypre_SStructGraphGrid(graph); hypre_SStructStencil *stencil = hypre_SStructGraphStencil(graph, part, var); int *vars = hypre_SStructStencilVars(stencil); hypre_Index *shape = hypre_SStructStencilShape(stencil); int size = hypre_SStructStencilSize(stencil); hypre_IndexRef offset; hypre_BoxMap *map; hypre_BoxMapEntry **map_entries; int nmap_entries; hypre_BoxMapEntry **map_to_entries; int nmap_to_entries; int nrows; int *ncols; HYPRE_BigInt *rows; HYPRE_BigInt *cols; double *ijvalues; hypre_Box *box; hypre_Box *to_box; hypre_Box *map_box; hypre_Box *int_box; hypre_Index index; hypre_Index rs, cs; int sy, sz; HYPRE_BigInt row_base, col_base; int val_base; int e, entry, ii, jj, i, j, k; int proc, myproc; /* GEC1002 the matrix type */ int matrix_type = hypre_SStructMatrixObjectType(matrix); box = hypre_BoxCreate(); /*------------------------------------------ * all stencil entries *------------------------------------------*/ if (entries[0] < size) { to_box = hypre_BoxCreate(); map_box = hypre_BoxCreate(); int_box = hypre_BoxCreate(); hypre_CopyIndex(ilower, hypre_BoxIMin(box)); hypre_CopyIndex(iupper, hypre_BoxIMax(box)); /* ZTODO: check that this change fixes multiple-entry problem */ nrows = hypre_BoxVolume(box)*nentries; ncols = hypre_CTAlloc(int, nrows); for (i = 0; i < nrows; i++) { ncols[i] = 1; } rows = hypre_CTAlloc(HYPRE_BigInt, nrows); cols = hypre_CTAlloc(HYPRE_BigInt, nrows); ijvalues = hypre_CTAlloc(double, nrows); sy = (hypre_IndexX(iupper) - hypre_IndexX(ilower) + 1); sz = (hypre_IndexY(iupper) - hypre_IndexY(ilower) + 1) * sy; map = hypre_SStructGridMap(grid, part, var); hypre_BoxMapIntersect(map, ilower, iupper, &map_entries, &nmap_entries); for (ii = 0; ii < nmap_entries; ii++) { /* Only Set values if I am the owner process; off-process AddTo and Get * values are done by IJ */ if (!add_to) { hypre_SStructMapEntryGetProcess(map_entries[ii], &proc); MPI_Comm_rank(hypre_SStructGridComm(grid), &myproc); if (proc != myproc) { continue; } } /* GEC1002 introducing the strides based on the type of the matrix */ hypre_SStructMapEntryGetStrides(map_entries[ii], rs, matrix_type); hypre_CopyIndex(ilower, hypre_BoxIMin(box)); hypre_CopyIndex(iupper, hypre_BoxIMax(box)); hypre_BoxMapEntryGetExtents(map_entries[ii], hypre_BoxIMin(map_box), hypre_BoxIMax(map_box)); hypre_IntersectBoxes(box, map_box, int_box); hypre_CopyBox(int_box, box); nrows = 0; for (e = 0; e < nentries; e++) { entry = entries[e]; hypre_CopyBox(box, to_box); offset = shape[entry]; hypre_BoxIMinX(to_box) += hypre_IndexX(offset); hypre_BoxIMinY(to_box) += hypre_IndexY(offset); hypre_BoxIMinZ(to_box) += hypre_IndexZ(offset); hypre_BoxIMaxX(to_box) += hypre_IndexX(offset); hypre_BoxIMaxY(to_box) += hypre_IndexY(offset); hypre_BoxIMaxZ(to_box) += hypre_IndexZ(offset); map = hypre_SStructGridMap(grid, part, vars[entry]); hypre_BoxMapIntersect(map, hypre_BoxIMin(to_box), hypre_BoxIMax(to_box), &map_to_entries, &nmap_to_entries ); for (jj = 0; jj < nmap_to_entries; jj++) { /* GEC1002 introducing the strides based on the type of the matrix */ hypre_SStructMapEntryGetStrides(map_to_entries[jj], cs, matrix_type); hypre_BoxMapEntryGetExtents(map_to_entries[jj], hypre_BoxIMin(map_box), hypre_BoxIMax(map_box)); hypre_IntersectBoxes(to_box, map_box, int_box); hypre_CopyIndex(hypre_BoxIMin(int_box), index); /* GEC1002 introducing the rank based on the type of the matrix */ hypre_SStructMapEntryGetGlobalRank(map_to_entries[jj], index, &col_base,matrix_type); hypre_IndexX(index) -= hypre_IndexX(offset); hypre_IndexY(index) -= hypre_IndexY(offset); hypre_IndexZ(index) -= hypre_IndexZ(offset); /* GEC1002 introducing the rank based on the type of the matrix */ hypre_SStructMapEntryGetGlobalRank(map_entries[ii], index, &row_base,matrix_type); hypre_IndexX(index) -= hypre_IndexX(ilower); hypre_IndexY(index) -= hypre_IndexY(ilower); hypre_IndexZ(index) -= hypre_IndexZ(ilower); val_base = e + (hypre_IndexX(index) + hypre_IndexY(index)*sy + hypre_IndexZ(index)*sz) * nentries; for (k = 0; k < hypre_BoxSizeZ(int_box); k++) { for (j = 0; j < hypre_BoxSizeY(int_box); j++) { for (i = 0; i < hypre_BoxSizeX(int_box); i++) { rows[nrows] = row_base + (HYPRE_BigInt)(i*rs[0] + j*rs[1] + k*rs[2]); cols[nrows] = col_base + (HYPRE_BigInt)(i*cs[0] + j*cs[1] + k*cs[2]); ijvalues[nrows] = values[val_base + (i + j*sy + k*sz)*nentries]; nrows++; } } } } hypre_TFree(map_to_entries); } /*------------------------------------------ * set IJ values one stencil entry at a time *------------------------------------------*/ if (add_to > 0) { HYPRE_IJMatrixAddToValues(ijmatrix, nrows, ncols, (const HYPRE_BigInt *) rows, (const HYPRE_BigInt *) cols, (const double *) ijvalues); } else if (add_to > -1) { HYPRE_IJMatrixSetValues(ijmatrix, nrows, ncols, (const HYPRE_BigInt *) rows, (const HYPRE_BigInt *) cols, (const double *) ijvalues); } else { HYPRE_IJMatrixGetValues(ijmatrix, nrows, ncols, rows, cols, values); } } hypre_TFree(map_entries); hypre_TFree(ncols); hypre_TFree(rows); hypre_TFree(cols); hypre_TFree(ijvalues); hypre_BoxDestroy(to_box); hypre_BoxDestroy(map_box); hypre_BoxDestroy(int_box); }
int hypre_SStructUMatrixSetValues( hypre_SStructMatrix *matrix, int part, hypre_Index index, int var, int nentries, int *entries, double *values, int add_to ) { HYPRE_IJMatrix ijmatrix = hypre_SStructMatrixIJMatrix(matrix); hypre_SStructGraph *graph = hypre_SStructMatrixGraph(matrix); hypre_SStructGrid *grid = hypre_SStructGraphGrid(graph); hypre_SStructStencil *stencil = hypre_SStructGraphStencil(graph, part, var); int *vars = hypre_SStructStencilVars(stencil); hypre_Index *shape = hypre_SStructStencilShape(stencil); int size = hypre_SStructStencilSize(stencil); hypre_IndexRef offset; hypre_Index to_index; hypre_SStructUVEntry *Uventry; hypre_BoxMapEntry *map_entry; hypre_SStructMapInfo *entry_info; HYPRE_BigInt row_coord; HYPRE_BigInt *col_coords; int ncoeffs; double *coeffs; int i, entry; int proc, myproc; /* GEC1002 the matrix type */ int matrix_type = hypre_SStructMatrixObjectType(matrix); hypre_SStructGridFindMapEntry(grid, part, index, var, &map_entry); if (map_entry == NULL) { hypre_error_in_arg(1); hypre_error_in_arg(2); hypre_error_in_arg(3); /* RDF: This printing shouldn't be on by default */ printf("Warning: Attempt to set coeffs for point not in grid\n"); printf("hypre_SStructUMatrixSetValues call aborted for grid point\n"); printf(" part=%d, var=%d, index=(%d, %d, %d)\n", part, var, hypre_IndexD(index,0), hypre_IndexD(index,1), hypre_IndexD(index,2) ); return hypre_error_flag; } else { hypre_BoxMapEntryGetInfo(map_entry, (void **) &entry_info); } /* Only Set values if I am the owner process; off-process AddTo and Get * values are done by IJ */ if (!add_to) { hypre_SStructMapEntryGetProcess(map_entry, &proc); MPI_Comm_rank(hypre_SStructGridComm(grid), &myproc); if (proc != myproc) { return hypre_error_flag; } } /* GEC1002 get the rank using the function with the type=matrixtype*/ hypre_SStructMapEntryGetGlobalRank(map_entry, index, &row_coord, matrix_type); col_coords = hypre_SStructMatrixTmpColCoords(matrix); coeffs = hypre_SStructMatrixTmpCoeffs(matrix); ncoeffs = 0; for (i = 0; i < nentries; i++) { entry = entries[i]; if (entry < size) { /* stencil entries */ offset = shape[entry]; hypre_IndexX(to_index) = hypre_IndexX(index) + hypre_IndexX(offset); hypre_IndexY(to_index) = hypre_IndexY(index) + hypre_IndexY(offset); hypre_IndexZ(to_index) = hypre_IndexZ(index) + hypre_IndexZ(offset); hypre_SStructGridFindMapEntry(grid, part, to_index, vars[entry], &map_entry); if (map_entry != NULL) { hypre_SStructMapEntryGetGlobalRank(map_entry, to_index, &col_coords[ncoeffs],matrix_type); coeffs[ncoeffs] = values[i]; ncoeffs++; } } else { /* non-stencil entries */ entry -= size; hypre_SStructGraphFindUVEntry(graph, part, index, var, &Uventry); col_coords[ncoeffs] = hypre_SStructUVEntryRank(Uventry, entry); coeffs[ncoeffs] = values[i]; ncoeffs++; } } if (add_to > 0) { HYPRE_IJMatrixAddToValues(ijmatrix, 1, &ncoeffs, &row_coord, (const HYPRE_BigInt *) col_coords, (const double *) coeffs); } else if (add_to > -1) { HYPRE_IJMatrixSetValues(ijmatrix, 1, &ncoeffs, &row_coord, (const HYPRE_BigInt *) col_coords, (const double *) coeffs); } else { HYPRE_IJMatrixGetValues(ijmatrix, 1, &ncoeffs, &row_coord, col_coords, values); } return hypre_error_flag; }
inline void numfact(unsigned int ncol, int* I, int* loc2glob, int* J, K* C) { static_assert(std::is_same<double, K>::value, "Hypre only supports double-precision floating-point real numbers"); static_assert(S == 'G', "Hypre only supports nonsymmetric matrices"); HYPRE_IJMatrixCreate(DMatrix::_communicator, loc2glob[0], loc2glob[1], loc2glob[0], loc2glob[1], &_A); HYPRE_IJMatrixSetObjectType(_A, HYPRE_PARCSR); HYPRE_IJMatrixSetRowSizes(_A, I + 1); _local = ncol; int* rows = new int[3 * _local](); int* diag_sizes = rows + _local; int* offdiag_sizes = diag_sizes + _local; rows[0] = I[0]; for(unsigned int i = 0; i < _local; ++i) { std::for_each(J + rows[0], J + rows[0] + I[i + 1], [&](int& j) { (j < loc2glob[0] || loc2glob[1] < j) ? ++offdiag_sizes[i] : ++diag_sizes[i]; }); rows[0] += I[i + 1]; } HYPRE_IJMatrixSetDiagOffdSizes(_A, diag_sizes, offdiag_sizes); HYPRE_IJMatrixSetMaxOffProcElmts(_A, 0); HYPRE_IJMatrixInitialize(_A); std::iota(rows, rows + _local, loc2glob[0]); HYPRE_IJMatrixSetValues(_A, _local, I + 1, rows, J, C); HYPRE_IJMatrixAssemble(_A); HYPRE_IJVectorCreate(DMatrix::_communicator, loc2glob[0], loc2glob[1], &_b); HYPRE_IJVectorSetObjectType(_b, HYPRE_PARCSR); HYPRE_IJVectorInitialize(_b); HYPRE_IJVectorCreate(DMatrix::_communicator, loc2glob[0], loc2glob[1], &_x); HYPRE_IJVectorSetObjectType(_x, HYPRE_PARCSR); HYPRE_IJVectorInitialize(_x); delete [] rows; delete [] I; delete [] loc2glob; HYPRE_BoomerAMGCreate(_strategy == 1 ? &_solver : &_precond); HYPRE_BoomerAMGSetCoarsenType(_strategy == 1 ? _solver : _precond, 6); /* Falgout coarsening */ HYPRE_BoomerAMGSetRelaxType(_strategy == 1 ? _solver : _precond, 6); /* G-S/Jacobi hybrid relaxation */ HYPRE_BoomerAMGSetNumSweeps(_strategy == 1 ? _solver : _precond, 1); /* sweeps on each level */ HYPRE_BoomerAMGSetMaxLevels(_strategy == 1 ? _solver : _precond, 10); /* maximum number of levels */ HYPRE_ParCSRMatrix parcsr_A; HYPRE_IJMatrixGetObject(_A, reinterpret_cast<void**>(&parcsr_A)); HYPRE_ParVector par_b; HYPRE_IJVectorGetObject(_b, reinterpret_cast<void**>(&par_b)); HYPRE_ParVector par_x; HYPRE_IJVectorGetObject(_x, reinterpret_cast<void**>(&par_x)); if(_strategy == 1) { HYPRE_BoomerAMGSetTol(_solver, 1.0e-8); HYPRE_BoomerAMGSetMaxIter(_solver, 1000); HYPRE_BoomerAMGSetPrintLevel(_solver, 1); HYPRE_BoomerAMGSetup(_solver, parcsr_A, nullptr, nullptr); } else { HYPRE_BoomerAMGSetTol(_precond, 0.0); HYPRE_BoomerAMGSetMaxIter(_precond, 1); HYPRE_BoomerAMGSetPrintLevel(_precond, 1); if(_strategy == 2) { HYPRE_ParCSRPCGCreate(DMatrix::_communicator, &_solver); HYPRE_PCGSetMaxIter(_solver, 500); HYPRE_PCGSetTol(_solver, 1.0e-8); HYPRE_PCGSetTwoNorm(_solver, 1); HYPRE_PCGSetPrintLevel(_solver, 1); HYPRE_PCGSetLogging(_solver, 1); HYPRE_PCGSetPrecond(_solver, reinterpret_cast<HYPRE_PtrToSolverFcn>(HYPRE_BoomerAMGSolve), reinterpret_cast<HYPRE_PtrToSolverFcn>(HYPRE_BoomerAMGSetup), _precond); HYPRE_ParCSRPCGSetup(_solver, parcsr_A, par_b, par_x); } else { HYPRE_ParCSRFlexGMRESCreate(DMatrix::_communicator, &_solver); HYPRE_FlexGMRESSetKDim(_solver, 50); HYPRE_FlexGMRESSetMaxIter(_solver, 500); HYPRE_FlexGMRESSetTol(_solver, 1.0e-8); HYPRE_FlexGMRESSetPrintLevel(_solver, 1); HYPRE_FlexGMRESSetLogging(_solver, 1); HYPRE_FlexGMRESSetPrecond(_solver, reinterpret_cast<HYPRE_PtrToSolverFcn>(HYPRE_BoomerAMGSolve), reinterpret_cast<HYPRE_PtrToSolverFcn>(HYPRE_BoomerAMGSetup), _precond); HYPRE_ParCSRFlexGMRESSetup(_solver, parcsr_A, par_b, par_x); } } }
int main (int argc, char *argv[]) { HYPRE_Int i; int myid, num_procs; int N, n; HYPRE_Int ilower, iupper; HYPRE_Int local_size, extra; int solver_id; int print_solution, print_system; double h, h2; HYPRE_IJMatrix A; HYPRE_ParCSRMatrix parcsr_A; HYPRE_IJVector b; HYPRE_ParVector par_b; HYPRE_IJVector x; HYPRE_ParVector par_x; HYPRE_Solver solver, precond; /* Initialize MPI */ MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myid); MPI_Comm_size(MPI_COMM_WORLD, &num_procs); /* Default problem parameters */ n = 33; solver_id = 0; print_solution = 0; print_system = 0; /* Parse command line */ { int arg_index = 0; int print_usage = 0; while (arg_index < argc) { if ( strcmp(argv[arg_index], "-n") == 0 ) { arg_index++; n = atoi(argv[arg_index++]); } else if ( strcmp(argv[arg_index], "-solver") == 0 ) { arg_index++; solver_id = atoi(argv[arg_index++]); } else if ( strcmp(argv[arg_index], "-print_solution") == 0 ) { arg_index++; print_solution = 1; } else if ( strcmp(argv[arg_index], "-print_system") == 0 ) { arg_index++; print_system = 1; } else if ( strcmp(argv[arg_index], "-help") == 0 ) { print_usage = 1; break; } else { arg_index++; } } if ((print_usage) && (myid == 0)) { printf("\n"); printf("Usage: %s [<options>]\n", argv[0]); printf("\n"); printf(" -n <n> : problem size in each direction (default: 33)\n"); printf(" -solver <ID> : solver ID\n"); printf(" 0 - AMG (default) \n"); printf(" 1 - AMG-PCG\n"); printf(" 8 - ParaSails-PCG\n"); printf(" 50 - PCG\n"); printf(" 61 - AMG-FlexGMRES\n"); printf(" -print_solution : print the solution vector\n"); printf(" -print_system : print the matrix and rhs\n"); printf("\n"); } if (print_usage) { MPI_Finalize(); return (0); } } /* Preliminaries: want at least one processor per row */ if (n*n < num_procs) n = sqrt(num_procs) + 1; N = n*n; /* global number of rows */ h = 1.0/(n+1); /* mesh size*/ h2 = h*h; /* Each processor knows only of its own rows - the range is denoted by ilower and upper. Here we partition the rows. We account for the fact that N may not divide evenly by the number of processors. */ local_size = N/num_procs; extra = N - local_size*num_procs; ilower = local_size*myid; ilower += hypre_min(myid, extra); iupper = local_size*(myid+1); iupper += hypre_min(myid+1, extra); iupper = iupper - 1; /* How many rows do I have? */ local_size = iupper - ilower + 1; /* Create the matrix. Note that this is a square matrix, so we indicate the row partition size twice (since number of rows = number of cols) */ HYPRE_IJMatrixCreate(MPI_COMM_WORLD, ilower, iupper, ilower, iupper, &A); /* Choose a parallel csr format storage (see the User's Manual) */ HYPRE_IJMatrixSetObjectType(A, HYPRE_PARCSR); /* Initialize before setting coefficients */ HYPRE_IJMatrixInitialize(A); /* Now go through my local rows and set the matrix entries. Each row has at most 5 entries. For example, if n=3: A = [M -I 0; -I M -I; 0 -I M] M = [4 -1 0; -1 4 -1; 0 -1 4] Note that here we are setting one row at a time, though one could set all the rows together (see the User's Manual). */ { HYPRE_Int nnz; double values[5]; HYPRE_Int cols[5]; for (i = ilower; i <= iupper; i++) { nnz = 0; /* The left identity block:position i-n */ if ((i-n)>=0) { cols[nnz] = i-n; values[nnz] = -1.0; nnz++; } /* The left -1: position i-1 */ if (i%n) { cols[nnz] = i-1; values[nnz] = -1.0; nnz++; } /* Set the diagonal: position i */ cols[nnz] = i; values[nnz] = 4.0; nnz++; /* The right -1: position i+1 */ if ((i+1)%n) { cols[nnz] = i+1; values[nnz] = -1.0; nnz++; } /* The right identity block:position i+n */ if ((i+n)< N) { cols[nnz] = i+n; values[nnz] = -1.0; nnz++; } /* Set the values for row i */ HYPRE_IJMatrixSetValues(A, 1, &nnz, &i, cols, values); } } /* Assemble after setting the coefficients */ HYPRE_IJMatrixAssemble(A); /* Note: for the testing of small problems, one may wish to read in a matrix in IJ format (for the format, see the output files from the -print_system option). In this case, one would use the following routine: HYPRE_IJMatrixRead( <filename>, MPI_COMM_WORLD, HYPRE_PARCSR, &A ); <filename> = IJ.A.out to read in what has been printed out by -print_system (processor numbers are omitted). A call to HYPRE_IJMatrixRead is an *alternative* to the following sequence of HYPRE_IJMatrix calls: Create, SetObjectType, Initialize, SetValues, and Assemble */ /* Get the parcsr matrix object to use */ HYPRE_IJMatrixGetObject(A, (void**) &parcsr_A); /* Create the rhs and solution */ HYPRE_IJVectorCreate(MPI_COMM_WORLD, ilower, iupper,&b); HYPRE_IJVectorSetObjectType(b, HYPRE_PARCSR); HYPRE_IJVectorInitialize(b); HYPRE_IJVectorCreate(MPI_COMM_WORLD, ilower, iupper,&x); HYPRE_IJVectorSetObjectType(x, HYPRE_PARCSR); HYPRE_IJVectorInitialize(x); /* Set the rhs values to h^2 and the solution to zero */ { double *rhs_values, *x_values; HYPRE_Int *rows; rhs_values = calloc(local_size, sizeof(double)); x_values = calloc(local_size, sizeof(double)); rows = calloc(local_size, sizeof(HYPRE_Int)); for (i=0; i<local_size; i++) { rhs_values[i] = h2; x_values[i] = 0.0; rows[i] = ilower + i; } HYPRE_IJVectorSetValues(b, local_size, rows, rhs_values); HYPRE_IJVectorSetValues(x, local_size, rows, x_values); free(x_values); free(rhs_values); free(rows); } HYPRE_IJVectorAssemble(b); /* As with the matrix, for testing purposes, one may wish to read in a rhs: HYPRE_IJVectorRead( <filename>, MPI_COMM_WORLD, HYPRE_PARCSR, &b ); as an alternative to the following sequence of HYPRE_IJVectors calls: Create, SetObjectType, Initialize, SetValues, and Assemble */ HYPRE_IJVectorGetObject(b, (void **) &par_b); HYPRE_IJVectorAssemble(x); HYPRE_IJVectorGetObject(x, (void **) &par_x); /* Print out the system - files names will be IJ.out.A.XXXXX and IJ.out.b.XXXXX, where XXXXX = processor id */ if (print_system) { HYPRE_IJMatrixPrint(A, "IJ.out.A"); HYPRE_IJVectorPrint(b, "IJ.out.b"); } /* Choose a solver and solve the system */ /* AMG */ if (solver_id == 0) { HYPRE_Int num_iterations; double final_res_norm; /* Create solver */ HYPRE_BoomerAMGCreate(&solver); /* Set some parameters (See Reference Manual for more parameters) */ HYPRE_BoomerAMGSetPrintLevel(solver, 3); /* print solve info + parameters */ HYPRE_BoomerAMGSetCoarsenType(solver, 6); /* Falgout coarsening */ HYPRE_BoomerAMGSetRelaxType(solver, 3); /* G-S/Jacobi hybrid relaxation */ HYPRE_BoomerAMGSetNumSweeps(solver, 1); /* Sweeeps on each level */ HYPRE_BoomerAMGSetMaxLevels(solver, 20); /* maximum number of levels */ HYPRE_BoomerAMGSetTol(solver, 1e-7); /* conv. tolerance */ /* Now setup and solve! */ HYPRE_BoomerAMGSetup(solver, parcsr_A, par_b, par_x); HYPRE_BoomerAMGSolve(solver, parcsr_A, par_b, par_x); /* Run info - needed logging turned on */ HYPRE_BoomerAMGGetNumIterations(solver, &num_iterations); HYPRE_BoomerAMGGetFinalRelativeResidualNorm(solver, &final_res_norm); if (myid == 0) { printf("\n"); printf("Iterations = %lld\n", num_iterations); printf("Final Relative Residual Norm = %e\n", final_res_norm); printf("\n"); } /* Destroy solver */ HYPRE_BoomerAMGDestroy(solver); } /* PCG */ else if (solver_id == 50) { HYPRE_Int num_iterations; double final_res_norm; /* Create solver */ HYPRE_ParCSRPCGCreate(MPI_COMM_WORLD, &solver); /* Set some parameters (See Reference Manual for more parameters) */ HYPRE_PCGSetMaxIter(solver, 1000); /* max iterations */ HYPRE_PCGSetTol(solver, 1e-7); /* conv. tolerance */ HYPRE_PCGSetTwoNorm(solver, 1); /* use the two norm as the stopping criteria */ HYPRE_PCGSetPrintLevel(solver, 2); /* prints out the iteration info */ HYPRE_PCGSetLogging(solver, 1); /* needed to get run info later */ /* Now setup and solve! */ HYPRE_ParCSRPCGSetup(solver, parcsr_A, par_b, par_x); HYPRE_ParCSRPCGSolve(solver, parcsr_A, par_b, par_x); /* Run info - needed logging turned on */ HYPRE_PCGGetNumIterations(solver, &num_iterations); HYPRE_PCGGetFinalRelativeResidualNorm(solver, &final_res_norm); if (myid == 0) { printf("\n"); printf("Iterations = %lld\n", num_iterations); printf("Final Relative Residual Norm = %e\n", final_res_norm); printf("\n"); } /* Destroy solver */ HYPRE_ParCSRPCGDestroy(solver); } /* PCG with AMG preconditioner */ else if (solver_id == 1) { HYPRE_Int num_iterations; double final_res_norm; /* Create solver */ HYPRE_ParCSRPCGCreate(MPI_COMM_WORLD, &solver); /* Set some parameters (See Reference Manual for more parameters) */ HYPRE_PCGSetMaxIter(solver, 1000); /* max iterations */ HYPRE_PCGSetTol(solver, 1e-7); /* conv. tolerance */ HYPRE_PCGSetTwoNorm(solver, 1); /* use the two norm as the stopping criteria */ HYPRE_PCGSetPrintLevel(solver, 2); /* print solve info */ HYPRE_PCGSetLogging(solver, 1); /* needed to get run info later */ /* Now set up the AMG preconditioner and specify any parameters */ HYPRE_BoomerAMGCreate(&precond); HYPRE_BoomerAMGSetPrintLevel(precond, 1); /* print amg solution info */ HYPRE_BoomerAMGSetCoarsenType(precond, 6); HYPRE_BoomerAMGSetRelaxType(precond, 6); /* Sym G.S./Jacobi hybrid */ HYPRE_BoomerAMGSetNumSweeps(precond, 1); HYPRE_BoomerAMGSetTol(precond, 0.0); /* conv. tolerance zero */ HYPRE_BoomerAMGSetMaxIter(precond, 1); /* do only one iteration! */ /* Set the PCG preconditioner */ HYPRE_PCGSetPrecond(solver, (HYPRE_PtrToSolverFcn) HYPRE_BoomerAMGSolve, (HYPRE_PtrToSolverFcn) HYPRE_BoomerAMGSetup, precond); /* Now setup and solve! */ HYPRE_ParCSRPCGSetup(solver, parcsr_A, par_b, par_x); HYPRE_ParCSRPCGSolve(solver, parcsr_A, par_b, par_x); /* Run info - needed logging turned on */ HYPRE_PCGGetNumIterations(solver, &num_iterations); HYPRE_PCGGetFinalRelativeResidualNorm(solver, &final_res_norm); if (myid == 0) { printf("\n"); printf("Iterations = %lld\n", num_iterations); printf("Final Relative Residual Norm = %e\n", final_res_norm); printf("\n"); } /* Destroy solver and preconditioner */ HYPRE_ParCSRPCGDestroy(solver); HYPRE_BoomerAMGDestroy(precond); } /* PCG with Parasails Preconditioner */ else if (solver_id == 8) { HYPRE_Int num_iterations; double final_res_norm; int sai_max_levels = 1; double sai_threshold = 0.1; double sai_filter = 0.05; int sai_sym = 1; /* Create solver */ HYPRE_ParCSRPCGCreate(MPI_COMM_WORLD, &solver); /* Set some parameters (See Reference Manual for more parameters) */ HYPRE_PCGSetMaxIter(solver, 1000); /* max iterations */ HYPRE_PCGSetTol(solver, 1e-7); /* conv. tolerance */ HYPRE_PCGSetTwoNorm(solver, 1); /* use the two norm as the stopping criteria */ HYPRE_PCGSetPrintLevel(solver, 2); /* print solve info */ HYPRE_PCGSetLogging(solver, 1); /* needed to get run info later */ /* Now set up the ParaSails preconditioner and specify any parameters */ HYPRE_ParaSailsCreate(MPI_COMM_WORLD, &precond); /* Set some parameters (See Reference Manual for more parameters) */ HYPRE_ParaSailsSetParams(precond, sai_threshold, sai_max_levels); HYPRE_ParaSailsSetFilter(precond, sai_filter); HYPRE_ParaSailsSetSym(precond, sai_sym); HYPRE_ParaSailsSetLogging(precond, 3); /* Set the PCG preconditioner */ HYPRE_PCGSetPrecond(solver, (HYPRE_PtrToSolverFcn) HYPRE_ParaSailsSolve, (HYPRE_PtrToSolverFcn) HYPRE_ParaSailsSetup, precond); /* Now setup and solve! */ HYPRE_ParCSRPCGSetup(solver, parcsr_A, par_b, par_x); HYPRE_ParCSRPCGSolve(solver, parcsr_A, par_b, par_x); /* Run info - needed logging turned on */ HYPRE_PCGGetNumIterations(solver, &num_iterations); HYPRE_PCGGetFinalRelativeResidualNorm(solver, &final_res_norm); if (myid == 0) { printf("\n"); printf("Iterations = %lld\n", num_iterations); printf("Final Relative Residual Norm = %e\n", final_res_norm); printf("\n"); } /* Destory solver and preconditioner */ HYPRE_ParCSRPCGDestroy(solver); HYPRE_ParaSailsDestroy(precond); } /* Flexible GMRES with AMG Preconditioner */ else if (solver_id == 61) { HYPRE_Int num_iterations; double final_res_norm; int restart = 30; int modify = 1; /* Create solver */ HYPRE_ParCSRFlexGMRESCreate(MPI_COMM_WORLD, &solver); /* Set some parameters (See Reference Manual for more parameters) */ HYPRE_FlexGMRESSetKDim(solver, restart); HYPRE_FlexGMRESSetMaxIter(solver, 1000); /* max iterations */ HYPRE_FlexGMRESSetTol(solver, 1e-7); /* conv. tolerance */ HYPRE_FlexGMRESSetPrintLevel(solver, 2); /* print solve info */ HYPRE_FlexGMRESSetLogging(solver, 1); /* needed to get run info later */ /* Now set up the AMG preconditioner and specify any parameters */ HYPRE_BoomerAMGCreate(&precond); HYPRE_BoomerAMGSetPrintLevel(precond, 1); /* print amg solution info */ HYPRE_BoomerAMGSetCoarsenType(precond, 6); HYPRE_BoomerAMGSetRelaxType(precond, 6); /* Sym G.S./Jacobi hybrid */ HYPRE_BoomerAMGSetNumSweeps(precond, 1); HYPRE_BoomerAMGSetTol(precond, 0.0); /* conv. tolerance zero */ HYPRE_BoomerAMGSetMaxIter(precond, 1); /* do only one iteration! */ /* Set the FlexGMRES preconditioner */ HYPRE_FlexGMRESSetPrecond(solver, (HYPRE_PtrToSolverFcn) HYPRE_BoomerAMGSolve, (HYPRE_PtrToSolverFcn) HYPRE_BoomerAMGSetup, precond); if (modify) /* this is an optional call - if you don't call it, hypre_FlexGMRESModifyPCDefault is used - which does nothing. Otherwise, you can define your own, similar to the one used here */ HYPRE_FlexGMRESSetModifyPC( solver, (HYPRE_PtrToModifyPCFcn) hypre_FlexGMRESModifyPCAMGExample); /* Now setup and solve! */ HYPRE_ParCSRFlexGMRESSetup(solver, parcsr_A, par_b, par_x); HYPRE_ParCSRFlexGMRESSolve(solver, parcsr_A, par_b, par_x); /* Run info - needed logging turned on */ HYPRE_FlexGMRESGetNumIterations(solver, &num_iterations); HYPRE_FlexGMRESGetFinalRelativeResidualNorm(solver, &final_res_norm); if (myid == 0) { printf("\n"); printf("Iterations = %lld\n", num_iterations); printf("Final Relative Residual Norm = %e\n", final_res_norm); printf("\n"); } /* Destory solver and preconditioner */ HYPRE_ParCSRFlexGMRESDestroy(solver); HYPRE_BoomerAMGDestroy(precond); } else { if (myid ==0) printf("Invalid solver id specified.\n"); } /* Print the solution */ if (print_solution) HYPRE_IJVectorPrint(x, "ij.out.x"); /* Clean up */ HYPRE_IJMatrixDestroy(A); HYPRE_IJVectorDestroy(b); HYPRE_IJVectorDestroy(x); /* Finalize MPI*/ MPI_Finalize(); return(0); }
HYPRE_Int main (HYPRE_Int argc, char *argv[]) { HYPRE_Int i; HYPRE_Int myid, num_procs; HYPRE_Int N, n; HYPRE_Int ilower, iupper; HYPRE_Int local_size, extra; HYPRE_Int solver_id; HYPRE_Int print_solution; double h, h2; #ifdef HYPRE_FORTRAN hypre_F90_Obj A; hypre_F90_Obj parcsr_A; hypre_F90_Obj b; hypre_F90_Obj par_b; hypre_F90_Obj x; hypre_F90_Obj par_x; hypre_F90_Obj solver, precond; hypre_F90_Obj long_temp_COMM; HYPRE_Int temp_COMM; HYPRE_Int precond_id; HYPRE_Int one = 1; HYPRE_Int two = 2; HYPRE_Int three = 3; HYPRE_Int six = 6; HYPRE_Int twenty = 20; HYPRE_Int thousand = 1000; HYPRE_Int hypre_type = HYPRE_PARCSR; double oo1 = 1.e-3; double tol = 1.e-7; #else HYPRE_IJMatrix A; HYPRE_ParCSRMatrix parcsr_A; HYPRE_IJVector b; HYPRE_ParVector par_b; HYPRE_IJVector x; HYPRE_ParVector par_x; HYPRE_Solver solver, precond; #endif /* Initialize MPI */ hypre_MPI_Init(&argc, &argv); hypre_MPI_Comm_rank(hypre_MPI_COMM_WORLD, &myid); hypre_MPI_Comm_size(hypre_MPI_COMM_WORLD, &num_procs); /* Default problem parameters */ n = 33; solver_id = 0; print_solution = 0; /* Parse command line */ { HYPRE_Int arg_index = 0; HYPRE_Int print_usage = 0; while (arg_index < argc) { if ( strcmp(argv[arg_index], "-n") == 0 ) { arg_index++; n = atoi(argv[arg_index++]); } else if ( strcmp(argv[arg_index], "-solver") == 0 ) { arg_index++; solver_id = atoi(argv[arg_index++]); } else if ( strcmp(argv[arg_index], "-print_solution") == 0 ) { arg_index++; print_solution = 1; } else if ( strcmp(argv[arg_index], "-help") == 0 ) { print_usage = 1; break; } else { arg_index++; } } if ((print_usage) && (myid == 0)) { hypre_printf("\n"); hypre_printf("Usage: %s [<options>]\n", argv[0]); hypre_printf("\n"); hypre_printf(" -n <n> : problem size in each direction (default: 33)\n"); hypre_printf(" -solver <ID> : solver ID\n"); hypre_printf(" 0 - AMG (default) \n"); hypre_printf(" 1 - AMG-PCG\n"); hypre_printf(" 8 - ParaSails-PCG\n"); hypre_printf(" 50 - PCG\n"); hypre_printf(" -print_solution : print the solution vector\n"); hypre_printf("\n"); } if (print_usage) { hypre_MPI_Finalize(); return (0); } } /* Preliminaries: want at least one processor per row */ if (n*n < num_procs) n = sqrt(num_procs) + 1; N = n*n; /* global number of rows */ h = 1.0/(n+1); /* mesh size*/ h2 = h*h; /* Each processor knows only of its own rows - the range is denoted by ilower and upper. Here we partition the rows. We account for the fact that N may not divide evenly by the number of processors. */ local_size = N/num_procs; extra = N - local_size*num_procs; ilower = local_size*myid; ilower += hypre_min(myid, extra); iupper = local_size*(myid+1); iupper += hypre_min(myid+1, extra); iupper = iupper - 1; /* How many rows do I have? */ local_size = iupper - ilower + 1; /* Create the matrix. Note that this is a square matrix, so we indicate the row partition size twice (since number of rows = number of cols) */ #ifdef HYPRE_FORTRAN long_temp_COMM = (hypre_F90_Obj) hypre_MPI_COMM_WORLD; temp_COMM = (HYPRE_Int) hypre_MPI_COMM_WORLD; HYPRE_IJMatrixCreate(&long_temp_COMM, &ilower, &iupper, &ilower, &iupper, &A); #else HYPRE_IJMatrixCreate(hypre_MPI_COMM_WORLD, ilower, iupper, ilower, iupper, &A); #endif /* Choose a parallel csr format storage (see the User's Manual) */ #ifdef HYPRE_FORTRAN HYPRE_IJMatrixSetObjectType(&A, &hypre_type); #else HYPRE_IJMatrixSetObjectType(A, HYPRE_PARCSR); #endif /* Initialize before setting coefficients */ #ifdef HYPRE_FORTRAN HYPRE_IJMatrixInitialize(&A); #else HYPRE_IJMatrixInitialize(A); #endif /* Now go through my local rows and set the matrix entries. Each row has at most 5 entries. For example, if n=3: A = [M -I 0; -I M -I; 0 -I M] M = [4 -1 0; -1 4 -1; 0 -1 4] Note that here we are setting one row at a time, though one could set all the rows together (see the User's Manual). */ { HYPRE_Int nnz; double values[5]; HYPRE_Int cols[5]; for (i = ilower; i <= iupper; i++) { nnz = 0; /* The left identity block:position i-n */ if ((i-n)>=0) { cols[nnz] = i-n; values[nnz] = -1.0; nnz++; } /* The left -1: position i-1 */ if (i%n) { cols[nnz] = i-1; values[nnz] = -1.0; nnz++; } /* Set the diagonal: position i */ cols[nnz] = i; values[nnz] = 4.0; nnz++; /* The right -1: position i+1 */ if ((i+1)%n) { cols[nnz] = i+1; values[nnz] = -1.0; nnz++; } /* The right identity block:position i+n */ if ((i+n)< N) { cols[nnz] = i+n; values[nnz] = -1.0; nnz++; } /* Set the values for row i */ #ifdef HYPRE_FORTRAN HYPRE_IJMatrixSetValues(&A, &one, &nnz, &i, &cols[0], &values[0]); #else HYPRE_IJMatrixSetValues(A, 1, &nnz, &i, cols, values); #endif } } /* Assemble after setting the coefficients */ #ifdef HYPRE_FORTRAN HYPRE_IJMatrixAssemble(&A); #else HYPRE_IJMatrixAssemble(A); #endif /* Get the parcsr matrix object to use */ #ifdef HYPRE_FORTRAN HYPRE_IJMatrixGetObject(&A, &parcsr_A); HYPRE_IJMatrixGetObject(&A, &parcsr_A); #else HYPRE_IJMatrixGetObject(A, (void**) &parcsr_A); HYPRE_IJMatrixGetObject(A, (void**) &parcsr_A); #endif /* Create the rhs and solution */ #ifdef HYPRE_FORTRAN HYPRE_IJVectorCreate(&temp_COMM, &ilower, &iupper, &b); HYPRE_IJVectorSetObjectType(&b, &hypre_type); HYPRE_IJVectorInitialize(&b); #else HYPRE_IJVectorCreate(hypre_MPI_COMM_WORLD, ilower, iupper,&b); HYPRE_IJVectorSetObjectType(b, HYPRE_PARCSR); HYPRE_IJVectorInitialize(b); #endif #ifdef HYPRE_FORTRAN HYPRE_IJVectorCreate(&temp_COMM, &ilower, &iupper, &x); HYPRE_IJVectorSetObjectType(&x, &hypre_type); HYPRE_IJVectorInitialize(&x); #else HYPRE_IJVectorCreate(hypre_MPI_COMM_WORLD, ilower, iupper,&x); HYPRE_IJVectorSetObjectType(x, HYPRE_PARCSR); HYPRE_IJVectorInitialize(x); #endif /* Set the rhs values to h^2 and the solution to zero */ { double *rhs_values, *x_values; HYPRE_Int *rows; rhs_values = calloc(local_size, sizeof(double)); x_values = calloc(local_size, sizeof(double)); rows = calloc(local_size, sizeof(HYPRE_Int)); for (i=0; i<local_size; i++) { rhs_values[i] = h2; x_values[i] = 0.0; rows[i] = ilower + i; } #ifdef HYPRE_FORTRAN HYPRE_IJVectorSetValues(&b, &local_size, &rows[0], &rhs_values[0]); HYPRE_IJVectorSetValues(&x, &local_size, &rows[0], &x_values[0]); #else HYPRE_IJVectorSetValues(b, local_size, rows, rhs_values); HYPRE_IJVectorSetValues(x, local_size, rows, x_values); #endif free(x_values); free(rhs_values); free(rows); } #ifdef HYPRE_FORTRAN HYPRE_IJVectorAssemble(&b); HYPRE_IJVectorGetObject(&b, &par_b); #else HYPRE_IJVectorAssemble(b); HYPRE_IJVectorGetObject(b, (void **) &par_b); #endif #ifdef HYPRE_FORTRAN HYPRE_IJVectorAssemble(&x); HYPRE_IJVectorGetObject(&x, &par_x); #else HYPRE_IJVectorAssemble(x); HYPRE_IJVectorGetObject(x, (void **) &par_x); #endif /* Choose a solver and solve the system */ /* AMG */ if (solver_id == 0) { HYPRE_Int num_iterations; double final_res_norm; /* Create solver */ #ifdef HYPRE_FORTRAN HYPRE_BoomerAMGCreate(&solver); #else HYPRE_BoomerAMGCreate(&solver); #endif /* Set some parameters (See Reference Manual for more parameters) */ #ifdef HYPRE_FORTRAN HYPRE_BoomerAMGSetPrintLevel(&solver, &three); /* print solve info + parameters */ HYPRE_BoomerAMGSetCoarsenType(&solver, &six); /* Falgout coarsening */ HYPRE_BoomerAMGSetRelaxType(&solver, &three); /* G-S/Jacobi hybrid relaxation */ HYPRE_BoomerAMGSetNumSweeps(&solver, &one); /* Sweeeps on each level */ HYPRE_BoomerAMGSetMaxLevels(&solver, &twenty); /* maximum number of levels */ HYPRE_BoomerAMGSetTol(&solver, &tol); /* conv. tolerance */ #else HYPRE_BoomerAMGSetPrintLevel(solver, 3); /* print solve info + parameters */ HYPRE_BoomerAMGSetCoarsenType(solver, 6); /* Falgout coarsening */ HYPRE_BoomerAMGSetRelaxType(solver, 3); /* G-S/Jacobi hybrid relaxation */ HYPRE_BoomerAMGSetNumSweeps(solver, 1); /* Sweeeps on each level */ HYPRE_BoomerAMGSetMaxLevels(solver, 20); /* maximum number of levels */ HYPRE_BoomerAMGSetTol(solver, 1e-7); /* conv. tolerance */ #endif /* Now setup and solve! */ #ifdef HYPRE_FORTRAN HYPRE_BoomerAMGSetup(&solver, &parcsr_A, &par_b, &par_x); HYPRE_BoomerAMGSolve(&solver, &parcsr_A, &par_b, &par_x); #else HYPRE_BoomerAMGSetup(solver, parcsr_A, par_b, par_x); HYPRE_BoomerAMGSolve(solver, parcsr_A, par_b, par_x); #endif /* Run info - needed logging turned on */ #ifdef HYPRE_FORTRAN HYPRE_BoomerAMGGetNumIterations(&solver, &num_iterations); HYPRE_BoomerAMGGetFinalRelativeResidualNorm(&solver, &final_res_norm); #else HYPRE_BoomerAMGGetNumIterations(solver, &num_iterations); HYPRE_BoomerAMGGetFinalRelativeResidualNorm(solver, &final_res_norm); #endif if (myid == 0) { hypre_printf("\n"); hypre_printf("Iterations = %d\n", num_iterations); hypre_printf("Final Relative Residual Norm = %e\n", final_res_norm); hypre_printf("\n"); } /* Destroy solver */ #ifdef HYPRE_FORTRAN HYPRE_BoomerAMGDestroy(&solver); #else HYPRE_BoomerAMGDestroy(solver); #endif } /* PCG */ else if (solver_id == 50) { HYPRE_Int num_iterations; double final_res_norm; /* Create solver */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGCreate(&temp_COMM, &solver); #else HYPRE_ParCSRPCGCreate(hypre_MPI_COMM_WORLD, &solver); #endif /* Set some parameters (See Reference Manual for more parameters) */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGSetMaxIter(&solver, &thousand); /* max iterations */ HYPRE_ParCSRPCGSetTol(&solver, &tol); /* conv. tolerance */ HYPRE_ParCSRPCGSetTwoNorm(&solver, &one); /* use the two norm as the stopping criteria */ HYPRE_ParCSRPCGSetPrintLevel(&solver, &two); /* prints out the iteration info */ #else HYPRE_PCGSetMaxIter(solver, 1000); /* max iterations */ HYPRE_PCGSetTol(solver, 1e-7); /* conv. tolerance */ HYPRE_PCGSetTwoNorm(solver, 1); /* use the two norm as the stopping criteria */ HYPRE_PCGSetPrintLevel(solver, 2); /* prints out the iteration info */ HYPRE_PCGSetLogging(solver, 1); /* needed to get run info later */ #endif /* Now setup and solve! */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGSetup(&solver, &parcsr_A, &par_b, &par_x); HYPRE_ParCSRPCGSolve(&solver, &parcsr_A, &par_b, &par_x); #else HYPRE_ParCSRPCGSetup(solver, parcsr_A, par_b, par_x); HYPRE_ParCSRPCGSolve(solver, parcsr_A, par_b, par_x); #endif /* Run info - needed logging turned on */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGGetNumIterations(&solver, &num_iterations); HYPRE_ParCSRPCGGetFinalRelativeResidualNorm(&solver, &final_res_norm); #else HYPRE_PCGGetNumIterations(solver, &num_iterations); HYPRE_PCGGetFinalRelativeResidualNorm(solver, &final_res_norm); #endif if (myid == 0) { hypre_printf("\n"); hypre_printf("Iterations = %d\n", num_iterations); hypre_printf("Final Relative Residual Norm = %e\n", final_res_norm); hypre_printf("\n"); } /* Destroy solver */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGDestroy(&solver); #else HYPRE_ParCSRPCGDestroy(solver); #endif } /* PCG with AMG preconditioner */ else if (solver_id == 1) { HYPRE_Int num_iterations; double final_res_norm; /* Create solver */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGCreate(&temp_COMM, &solver); #else HYPRE_ParCSRPCGCreate(hypre_MPI_COMM_WORLD, &solver); #endif /* Set some parameters (See Reference Manual for more parameters) */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGSetMaxIter(&solver, &thousand); /* max iterations */ HYPRE_ParCSRPCGSetTol(&solver, &tol); /* conv. tolerance */ HYPRE_ParCSRPCGSetTwoNorm(&solver, &one); /* use the two norm as the stopping criteria */ HYPRE_ParCSRPCGSetPrintLevel(&solver, &two); /* print solve info */ #else HYPRE_PCGSetMaxIter(solver, 1000); /* max iterations */ HYPRE_PCGSetTol(solver, 1e-7); /* conv. tolerance */ HYPRE_PCGSetTwoNorm(solver, 1); /* use the two norm as the stopping criteria */ HYPRE_PCGSetPrintLevel(solver, 2); /* print solve info */ HYPRE_PCGSetLogging(solver, 1); /* needed to get run info later */ #endif /* Now set up the AMG preconditioner and specify any parameters */ #ifdef HYPRE_FORTRAN HYPRE_BoomerAMGCreate(&precond); HYPRE_BoomerAMGSetPrintLevel(&precond, &one); /* print amg solution info*/ HYPRE_BoomerAMGSetCoarsenType(&precond, &six); HYPRE_BoomerAMGSetRelaxType(&precond, &three); HYPRE_BoomerAMGSetNumSweeps(&precond, &one); HYPRE_BoomerAMGSetTol(&precond, &oo1); #else HYPRE_BoomerAMGCreate(&precond); HYPRE_BoomerAMGSetPrintLevel(precond, 1); /* print amg solution info*/ HYPRE_BoomerAMGSetCoarsenType(precond, 6); HYPRE_BoomerAMGSetRelaxType(precond, 3); HYPRE_BoomerAMGSetNumSweeps(precond, 1); HYPRE_BoomerAMGSetTol(precond, 1e-3); #endif /* Set the PCG preconditioner */ #ifdef HYPRE_FORTRAN precond_id = 2; HYPRE_ParCSRPCGSetPrecond(&solver, &precond_id, &precond); #else HYPRE_PCGSetPrecond(solver, (HYPRE_PtrToSolverFcn) HYPRE_BoomerAMGSolve, (HYPRE_PtrToSolverFcn) HYPRE_BoomerAMGSetup, precond); #endif /* Now setup and solve! */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGSetup(&solver, &parcsr_A, &par_b, &par_x); HYPRE_ParCSRPCGSolve(&solver, &parcsr_A, &par_b, &par_x); #else HYPRE_ParCSRPCGSetup(solver, parcsr_A, par_b, par_x); HYPRE_ParCSRPCGSolve(solver, parcsr_A, par_b, par_x); #endif /* Run info - needed logging turned on */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGGetNumIterations(&solver, &num_iterations); HYPRE_ParCSRPCGGetFinalRelativeResidualNorm(&solver, &final_res_norm); #else HYPRE_PCGGetNumIterations(solver, &num_iterations); HYPRE_PCGGetFinalRelativeResidualNorm(solver, &final_res_norm); #endif if (myid == 0) { hypre_printf("\n"); hypre_printf("Iterations = %d\n", num_iterations); hypre_printf("Final Relative Residual Norm = %e\n", final_res_norm); hypre_printf("\n"); } /* Destroy solver and preconditioner */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGDestroy(&solver); HYPRE_BoomerAMGDestroy(&precond); #else HYPRE_ParCSRPCGDestroy(solver); HYPRE_BoomerAMGDestroy(precond); #endif } /* PCG with Parasails Preconditioner */ else if (solver_id == 8) { HYPRE_Int num_iterations; double final_res_norm; HYPRE_Int sai_max_levels = 1; double sai_threshold = 0.1; double sai_filter = 0.05; HYPRE_Int sai_sym = 1; /* Create solver */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGCreate(&temp_COMM, &solver); #else HYPRE_ParCSRPCGCreate(hypre_MPI_COMM_WORLD, &solver); #endif /* Set some parameters (See Reference Manual for more parameters) */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGSetMaxIter(&solver, &thousand); /* max iterations */ HYPRE_ParCSRPCGSetTol(&solver, &tol); /* conv. tolerance */ HYPRE_ParCSRPCGSetTwoNorm(&solver, &one); /* use the two norm as the stopping criteria */ HYPRE_ParCSRPCGSetPrintLevel(&solver, &two); /* print solve info */ #else HYPRE_PCGSetMaxIter(solver, 1000); /* max iterations */ HYPRE_PCGSetTol(solver, 1e-7); /* conv. tolerance */ HYPRE_PCGSetTwoNorm(solver, 1); /* use the two norm as the stopping criteria */ HYPRE_PCGSetPrintLevel(solver, 2); /* print solve info */ HYPRE_PCGSetLogging(solver, 1); /* needed to get run info later */ #endif /* Now set up the ParaSails preconditioner and specify any parameters */ #ifdef HYPRE_FORTRAN HYPRE_ParaSailsCreate(&temp_COMM, &precond); #else HYPRE_ParaSailsCreate(hypre_MPI_COMM_WORLD, &precond); #endif /* Set some parameters (See Reference Manual for more parameters) */ #ifdef HYPRE_FORTRAN HYPRE_ParaSailsSetParams(&precond, &sai_threshold, &sai_max_levels); HYPRE_ParaSailsSetFilter(&precond, &sai_filter); HYPRE_ParaSailsSetSym(&precond, &sai_sym); HYPRE_ParaSailsSetLogging(&precond, &three); #else HYPRE_ParaSailsSetParams(precond, sai_threshold, sai_max_levels); HYPRE_ParaSailsSetFilter(precond, sai_filter); HYPRE_ParaSailsSetSym(precond, sai_sym); HYPRE_ParaSailsSetLogging(precond, 3); #endif /* Set the PCG preconditioner */ #ifdef HYPRE_FORTRAN precond_id = 4; HYPRE_ParCSRPCGSetPrecond(&solver, &precond_id, &precond); #else HYPRE_PCGSetPrecond(solver, (HYPRE_PtrToSolverFcn) HYPRE_ParaSailsSolve, (HYPRE_PtrToSolverFcn) HYPRE_ParaSailsSetup, precond); #endif /* Now setup and solve! */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGSetup(&solver, &parcsr_A, &par_b, &par_x); HYPRE_ParCSRPCGSolve(&solver, &parcsr_A, &par_b, &par_x); #else HYPRE_ParCSRPCGSetup(solver, parcsr_A, par_b, par_x); HYPRE_ParCSRPCGSolve(solver, parcsr_A, par_b, par_x); #endif /* Run info - needed logging turned on */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGGetNumIterations(&solver, &num_iterations); HYPRE_ParCSRPCGGetFinalRelativeResidualNorm(&solver, &final_res_norm); #else HYPRE_PCGGetNumIterations(solver, &num_iterations); HYPRE_PCGGetFinalRelativeResidualNorm(solver, &final_res_norm); #endif if (myid == 0) { hypre_printf("\n"); hypre_printf("Iterations = %d\n", num_iterations); hypre_printf("Final Relative Residual Norm = %e\n", final_res_norm); hypre_printf("\n"); } /* Destory solver and preconditioner */ #ifdef HYPRE_FORTRAN HYPRE_ParCSRPCGDestroy(&solver); HYPRE_ParaSailsDestroy(&precond); #else HYPRE_ParCSRPCGDestroy(solver); HYPRE_ParaSailsDestroy(precond); #endif } else { if (myid ==0) hypre_printf("Invalid solver id specified.\n"); } /* Print the solution */ #ifdef HYPRE_FORTRAN if (print_solution) HYPRE_IJVectorPrint(&x, "ij.out.x"); #else if (print_solution) HYPRE_IJVectorPrint(x, "ij.out.x"); #endif /* Clean up */ #ifdef HYPRE_FORTRAN HYPRE_IJMatrixDestroy(&A); HYPRE_IJVectorDestroy(&b); HYPRE_IJVectorDestroy(&x); #else HYPRE_IJMatrixDestroy(A); HYPRE_IJVectorDestroy(b); HYPRE_IJVectorDestroy(x); #endif /* Finalize MPI*/ hypre_MPI_Finalize(); return(0); }
void HypreSolver3D::build_A() { HYPRE_IJMatrixCreate(MPI_COMM_WORLD, ilower, iupper, ilower, iupper, &A); HYPRE_IJMatrixSetObjectType(A, HYPRE_PARCSR); HYPRE_IJMatrixInitialize(A); const int N12 = N1*N2; const int N012 = N0*N1*N2; int nnz; double values[7]; int cols[7]; int i; for(int j=ilower; j<=iupper; j++) { nnz = 0; i = j%N12;//*((int)(j/(N12))); // North if ((i-N2)>=0) { cols[nnz] = j-N2; values[nnz] = -1.0; nnz++; } // Left if (i%N2) { cols[nnz] = j-1; values[nnz] = -1.0; nnz++; } // Center cols[nnz] = j; values[nnz] = 6.0; nnz++; // Right if ((i+1)%N2) { cols[nnz] = j+1; values[nnz] = -1.0; nnz++; } // South if ((i+N2)<N12) { cols[nnz] = j+N2; values[nnz] = -1.0; nnz++; } // Top if ((j+N12)<N012) { cols[nnz] = j+N12; values[nnz] = -1.0; nnz++; } // Bottom if ((j-N12)>=0) { cols[nnz] = j-N12; values[nnz] = -1.0; nnz++; } HYPRE_IJMatrixSetValues(A, 1, &nnz, &j, cols, values); } HYPRE_IJMatrixAssemble(A); HYPRE_IJMatrixGetObject(A, (void**) &parcsr_A); }
int main(int argc, char *argv[]) { int ierr = 0, i, forierr = 0; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else int rank = 0; Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; // char tmp; // if (rank==0) cout << "Press any key to continue..."<< endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); Comm.SetTracebackMode(0); // This should shut down any error traceback reporting int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if(verbose && MyPID==0) cout << Epetra_Version() << endl << endl; if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive."<<endl; // Redefine verbose to only print on PE 0 if(verbose && rank!=0) verbose = false; int NumMyEquations = 10000; int NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3); if(MyPID < 3) NumMyEquations++; // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0, Comm); // Get update list and number of local equations from newly created Map vector<int> MyGlobalElements(Map.NumMyElements()); Map.MyGlobalElements(&MyGlobalElements[0]); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor vector<int> NumNz(NumMyEquations); // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for(i = 0; i < NumMyEquations; i++) if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1)) NumNz[i] = 1; else NumNz[i] = 2; // Create a Epetra_Matrix Epetra_CrsMatrix A(Copy, Map, &NumNz[0]); EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 vector<double> Values(2); Values[0] = -1.0; Values[1] = -1.0; vector<int> Indices(2); double two = 2.0; int NumEntries; forierr = 0; for(i = 0; i < NumMyEquations; i++) { if(MyGlobalElements[i] == 0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == NumGlobalEquations-1) { Indices[0] = NumGlobalEquations-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } forierr += !(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0])==0); forierr += !(A.InsertGlobalValues(MyGlobalElements[i], 1, &two, &MyGlobalElements[i])>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); // Finish up A.FillComplete(); A.OptimizeStorage(); HYPRE_IJMatrix Matrix; int ilower = Map.MinMyGID(); int iupper = Map.MaxMyGID(); //printf("Proc[%d], ilower = %d, iupper = %d.\n", MyPID, ilower, iupper); HYPRE_IJMatrixCreate(MPI_COMM_WORLD, ilower, iupper, ilower, iupper, &Matrix); HYPRE_IJMatrixSetObjectType(Matrix, HYPRE_PARCSR); HYPRE_IJMatrixInitialize(Matrix); for(i = 0; i < A.NumMyRows(); i++){ int numElements; A.NumMyRowEntries(i, numElements); vector<int> my_indices; my_indices.resize(numElements); vector<double> my_values; my_values.resize(numElements); int numEntries; A.ExtractMyRowCopy(i, numElements, numEntries, &my_values[0], &my_indices[0]); for(int j = 0; j < numEntries; j++) { my_indices[j] = A.GCID(my_indices[j]); } int GlobalRow[1]; GlobalRow[0] = A.GRID(i); HYPRE_IJMatrixSetValues(Matrix, 1, &numEntries, GlobalRow, &my_indices[0], &my_values[0]); } HYPRE_IJMatrixAssemble(Matrix); EpetraExt_HypreIJMatrix JadA(Matrix); JadA.SetMaps(JadA.RowMatrixRowMap(), A.RowMatrixColMap()); // Create vectors for Power method Epetra_Vector q(Map); Epetra_Vector z(Map); z.Random(); Epetra_Vector resid(Map); Epetra_Flops flopcounter; A.SetFlopCounter(flopcounter); q.SetFlopCounter(A); z.SetFlopCounter(A); resid.SetFlopCounter(A); JadA.SetFlopCounter(A); if (verbose) cout << "=======================================" << endl << "Testing Jad using CrsMatrix as input..." << endl << "=======================================" << endl; A.ResetFlops(); powerMethodTests(A, JadA, Map, q, z, resid, verbose); #ifdef EPETRA_MPI MPI_Finalize() ; #endif return ierr ; }