/****************************************************************************** * * hypre_IJVectorDistributePar * * takes an IJVector generated for one processor and distributes it * across many processors according to vec_starts, * if vec_starts is NULL, it distributes them evenly? * *****************************************************************************/ HYPRE_Int hypre_IJVectorDistributePar(hypre_IJVector *vector, const HYPRE_Int *vec_starts) { hypre_ParVector *old_vector = hypre_IJVectorObject(vector); hypre_ParVector *par_vector; HYPRE_Int print_level = hypre_IJVectorPrintLevel(vector); if (!old_vector) { if (print_level) { hypre_printf("old_vector == NULL -- "); hypre_printf("hypre_IJVectorDistributePar\n"); hypre_printf("**** Vector storage is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } par_vector = hypre_VectorToParVector(hypre_ParVectorComm(old_vector), hypre_ParVectorLocalVector(old_vector), (HYPRE_Int *)vec_starts); if (!par_vector) { if (print_level) { hypre_printf("par_vector == NULL -- "); hypre_printf("hypre_IJVectorDistributePar\n"); hypre_printf("**** Vector storage is unallocated ****\n"); } hypre_error_in_arg(1); } hypre_ParVectorDestroy(old_vector); hypre_IJVectorObject(vector) = par_vector; return hypre_error_flag; }
int HYPRE_IJVectorGetObject( HYPRE_IJVector vector, void **object ) { hypre_IJVector *vec = (hypre_IJVector *) vector; if (!vec) { printf("Variable vec is NULL -- HYPRE_IJVectorGetObject\n"); hypre_error_in_arg(1); return hypre_error_flag; } *object = hypre_IJVectorObject(vec); return hypre_error_flag; }
/****************************************************************************** * * hypre_IJVectorInitializePar * * initializes ParVector of IJVectorPar * *****************************************************************************/ HYPRE_Int hypre_IJVectorInitializePar(hypre_IJVector *vector) { hypre_ParVector *par_vector = hypre_IJVectorObject(vector); hypre_AuxParVector *aux_vector = hypre_IJVectorTranslator(vector); HYPRE_Int *partitioning = hypre_ParVectorPartitioning(par_vector); hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector); HYPRE_Int my_id; HYPRE_Int print_level = hypre_IJVectorPrintLevel(vector); MPI_Comm comm = hypre_IJVectorComm(vector); hypre_MPI_Comm_rank(comm,&my_id); if (!partitioning) { if (print_level) { hypre_printf("No ParVector partitioning for initialization -- "); hypre_printf("hypre_IJVectorInitializePar\n"); } hypre_error_in_arg(1); } #ifdef HYPRE_NO_GLOBAL_PARTITION hypre_VectorSize(local_vector) = partitioning[1] - partitioning[0]; #else hypre_VectorSize(local_vector) = partitioning[my_id+1] - partitioning[my_id]; #endif hypre_ParVectorInitialize(par_vector); if (!aux_vector) { hypre_AuxParVectorCreate(&aux_vector); hypre_IJVectorTranslator(vector) = aux_vector; } hypre_AuxParVectorInitialize(aux_vector); return hypre_error_flag; }
inline void solve(K* rhs) { hypre_Vector* loc = hypre_ParVectorLocalVector(reinterpret_cast<hypre_ParVector*>(hypre_IJVectorObject(reinterpret_cast<hypre_IJVector*>(_b)))); K* b = loc->data; loc->data = rhs; HYPRE_ParVector par_b; HYPRE_IJVectorGetObject(_b, reinterpret_cast<void**>(&par_b)); HYPRE_ParVector par_x; HYPRE_IJVectorGetObject(_x, reinterpret_cast<void**>(&par_x)); HYPRE_ParCSRMatrix parcsr_A; HYPRE_IJMatrixGetObject(_A, reinterpret_cast<void**>(&parcsr_A)); if(_strategy == 1) /* AMG */ HYPRE_BoomerAMGSolve(_solver, parcsr_A, par_b, par_x); else if(_strategy == 2) /* PCG with AMG */ HYPRE_ParCSRPCGSolve(_solver, parcsr_A, par_b, par_x); else /* GMRES with AMG */ HYPRE_ParCSRFlexGMRESSolve(_solver, parcsr_A, par_b, par_x); loc->data = b; loc = hypre_ParVectorLocalVector(reinterpret_cast<hypre_ParVector*>(hypre_IJVectorObject(reinterpret_cast<hypre_IJVector*>(_x)))); std::copy(loc->data, loc->data + _local, rhs); }
int HYPRE_IJVectorInitialize( HYPRE_IJVector vector ) { hypre_IJVector *vec = (hypre_IJVector *) vector; if (!vec) { printf("Vector variable is NULL -- HYPRE_IJVectorInitialize\n"); hypre_error_in_arg(1); return hypre_error_flag; } /* if ( hypre_IJVectorObjectType(vec) == HYPRE_PETSC ) return( hypre_IJVectorInitializePETSc(vec) ); else if ( hypre_IJVectorObjectType(vec) == HYPRE_ISIS ) return( hypre_IJVectorInitializeISIS(vec) ); else */ if ( hypre_IJVectorObjectType(vec) == HYPRE_PARCSR ) { if (!hypre_IJVectorObject(vec)) hypre_IJVectorCreatePar(vec, hypre_IJVectorPartitioning(vec)); hypre_IJVectorInitializePar(vec); } else { printf("Unrecognized object type -- HYPRE_IJVectorInitialize\n"); hypre_error_in_arg(1); } return hypre_error_flag; }
/****************************************************************************** * * hypre_IJVectorCreatePar * * creates ParVector if necessary, and leaves a pointer to it as the * hypre_IJVector object * *****************************************************************************/ int hypre_IJVectorCreatePar(hypre_IJVector *vector, HYPRE_BigInt *IJpartitioning) { MPI_Comm comm = hypre_IJVectorComm(vector); int num_procs, j; HYPRE_BigInt global_n, *partitioning, jmin; MPI_Comm_size(comm, &num_procs); #ifdef HYPRE_NO_GLOBAL_PARTITION jmin = hypre_IJVectorGlobalFirstRow(vector); global_n = hypre_IJVectorGlobalNumRows(vector); partitioning = hypre_CTAlloc(HYPRE_BigInt, 2); /* Shift to zero-based partitioning for ParVector object */ for (j = 0; j < 2; j++) partitioning[j] = IJpartitioning[j] - jmin; #else jmin = IJpartitioning[0]; global_n = IJpartitioning[num_procs] - jmin; partitioning = hypre_CTAlloc(HYPRE_BigInt, num_procs+1); /* Shift to zero-based partitioning for ParVector object */ for (j = 0; j < num_procs+1; j++) partitioning[j] = IJpartitioning[j] - jmin; #endif hypre_IJVectorObject(vector) = hypre_ParVectorCreate(comm, global_n, (HYPRE_BigInt *) partitioning); return hypre_error_flag; }
/****************************************************************************** * * hypre_IJVectorDestroyPar * * frees ParVector local storage of an IJVectorPar * *****************************************************************************/ HYPRE_Int hypre_IJVectorDestroyPar(hypre_IJVector *vector) { return hypre_ParVectorDestroy(hypre_IJVectorObject(vector)); }
/****************************************************************************** * * hypre_IJVectorAddToValuesPar * * adds to a potentially noncontiguous set of IJVectorPar components * *****************************************************************************/ HYPRE_Int hypre_IJVectorAddToValuesPar(hypre_IJVector *vector, HYPRE_Int num_values, const HYPRE_Int *indices, const double *values ) { HYPRE_Int my_id; HYPRE_Int i, j, vec_start, vec_stop; double *data; HYPRE_Int print_level = hypre_IJVectorPrintLevel(vector); HYPRE_Int *IJpartitioning = hypre_IJVectorPartitioning(vector); hypre_ParVector *par_vector = hypre_IJVectorObject(vector); hypre_AuxParVector *aux_vector = hypre_IJVectorTranslator(vector); MPI_Comm comm = hypre_IJVectorComm(vector); hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector); /* If no components are to be retrieved, perform no checking and return */ if (num_values < 1) return 0; hypre_MPI_Comm_rank(comm, &my_id); /* If par_vector == NULL or partitioning == NULL or local_vector == NULL let user know of catastrophe and exit */ if (!par_vector) { if (print_level) { hypre_printf("par_vector == NULL -- "); hypre_printf("hypre_IJVectorAddToValuesPar\n"); hypre_printf("**** Vector storage is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } if (!IJpartitioning) { if (print_level) { hypre_printf("IJpartitioning == NULL -- "); hypre_printf("hypre_IJVectorAddToValuesPar\n"); hypre_printf("**** IJVector partitioning is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } if (!local_vector) { if (print_level) { hypre_printf("local_vector == NULL -- "); hypre_printf("hypre_IJVectorAddToValuesPar\n"); hypre_printf("**** Vector local data is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } #ifdef HYPRE_NO_GLOBAL_PARTITION vec_start = IJpartitioning[0]; vec_stop = IJpartitioning[1]-1; #else vec_start = IJpartitioning[my_id]; vec_stop = IJpartitioning[my_id+1]-1; #endif if (vec_start > vec_stop) { if (print_level) { hypre_printf("vec_start > vec_stop -- "); hypre_printf("hypre_IJVectorAddToValuesPar\n"); hypre_printf("**** This vector partitioning should not occur ****\n"); } hypre_error_in_arg(1); } /* Determine whether indices points to local indices only, and if not, store indices and values into auxiliary vector structure If indices == NULL, assume that num_values components are to be set in a block starting at vec_start. NOTE: If indices == NULL off processor values are ignored!!! */ /* if (indices) { for (i = 0; i < num_values; i++) { ierr += (indices[i] < vec_start); ierr += (indices[i] >= vec_stop); } } if (ierr) { hypre_printf("indices beyond local range -- "); hypre_printf("hypre_IJVectorAddToValuesPar\n"); hypre_printf("**** Indices specified are unusable ****\n"); exit(1); } */ data = hypre_VectorData(local_vector); if (indices) { HYPRE_Int current_num_elmts = hypre_AuxParVectorCurrentNumElmts(aux_vector); HYPRE_Int max_off_proc_elmts = hypre_AuxParVectorMaxOffProcElmts(aux_vector); HYPRE_Int *off_proc_i = hypre_AuxParVectorOffProcI(aux_vector); double *off_proc_data = hypre_AuxParVectorOffProcData(aux_vector); for (j = 0; j < num_values; j++) { i = indices[j]; if (i < vec_start || i > vec_stop) { /* if elements outside processor boundaries, store in off processor stash */ if (!max_off_proc_elmts) { max_off_proc_elmts = 100; hypre_AuxParVectorMaxOffProcElmts(aux_vector) = max_off_proc_elmts; hypre_AuxParVectorOffProcI(aux_vector) = hypre_CTAlloc(HYPRE_Int,max_off_proc_elmts); hypre_AuxParVectorOffProcData(aux_vector) = hypre_CTAlloc(double,max_off_proc_elmts); off_proc_i = hypre_AuxParVectorOffProcI(aux_vector); off_proc_data = hypre_AuxParVectorOffProcData(aux_vector); } else if (current_num_elmts + 1 > max_off_proc_elmts) { max_off_proc_elmts += 10; off_proc_i = hypre_TReAlloc(off_proc_i,HYPRE_Int,max_off_proc_elmts); off_proc_data = hypre_TReAlloc(off_proc_data,double, max_off_proc_elmts); hypre_AuxParVectorMaxOffProcElmts(aux_vector) = max_off_proc_elmts; hypre_AuxParVectorOffProcI(aux_vector) = off_proc_i; hypre_AuxParVectorOffProcData(aux_vector) = off_proc_data; } off_proc_i[current_num_elmts] = i; off_proc_data[current_num_elmts++] = values[j]; hypre_AuxParVectorCurrentNumElmts(aux_vector)=current_num_elmts; }
/****************************************************************************** * * hypre_IJVectorSetValuesPar * * sets a potentially noncontiguous set of components of an IJVectorPar * *****************************************************************************/ HYPRE_Int hypre_IJVectorSetValuesPar(hypre_IJVector *vector, HYPRE_Int num_values, const HYPRE_Int *indices, const double *values ) { HYPRE_Int my_id; HYPRE_Int i, j, vec_start, vec_stop; double *data; HYPRE_Int print_level = hypre_IJVectorPrintLevel(vector); HYPRE_Int *IJpartitioning = hypre_IJVectorPartitioning(vector); hypre_ParVector *par_vector = hypre_IJVectorObject(vector); hypre_AuxParVector *aux_vector = hypre_IJVectorTranslator(vector); MPI_Comm comm = hypre_IJVectorComm(vector); hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector); /* If no components are to be set, perform no checking and return */ if (num_values < 1) return 0; hypre_MPI_Comm_rank(comm, &my_id); /* If par_vector == NULL or partitioning == NULL or local_vector == NULL let user know of catastrophe and exit */ if (!par_vector) { if (print_level) { hypre_printf("par_vector == NULL -- "); hypre_printf("hypre_IJVectorSetValuesPar\n"); hypre_printf("**** Vector storage is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } if (!IJpartitioning) { if (print_level) { hypre_printf("IJpartitioning == NULL -- "); hypre_printf("hypre_IJVectorSetValuesPar\n"); hypre_printf("**** IJVector partitioning is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } if (!local_vector) { if (print_level) { hypre_printf("local_vector == NULL -- "); hypre_printf("hypre_IJVectorSetValuesPar\n"); hypre_printf("**** Vector local data is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } #ifdef HYPRE_NO_GLOBAL_PARTITION vec_start = IJpartitioning[0]; vec_stop = IJpartitioning[1]-1; #else vec_start = IJpartitioning[my_id]; vec_stop = IJpartitioning[my_id+1]-1; #endif if (vec_start > vec_stop) { if (print_level) { hypre_printf("vec_start > vec_stop -- "); hypre_printf("hypre_IJVectorSetValuesPar\n"); hypre_printf("**** This vector partitioning should not occur ****\n"); } hypre_error_in_arg(1); } /* Determine whether indices points to local indices only, and if not, store indices and values into auxiliary vector structure If indices == NULL, assume that num_values components are to be set in a block starting at vec_start. NOTE: If indices == NULL off processor values are ignored!!! */ data = hypre_VectorData(local_vector); if (indices) { HYPRE_Int current_num_elmts = hypre_AuxParVectorCurrentNumElmts(aux_vector); /*HYPRE_Int max_off_proc_elmts = hypre_AuxParVectorMaxOffProcElmts(aux_vector);*/ HYPRE_Int *off_proc_i = hypre_AuxParVectorOffProcI(aux_vector); /*double *off_proc_data = hypre_AuxParVectorOffProcData(aux_vector);*/ HYPRE_Int cancel_indx = hypre_AuxParVectorCancelIndx(aux_vector); HYPRE_Int ii; for (j = 0; j < num_values; j++) { i = indices[j]; if (i < vec_start || i > vec_stop) { for (ii = 0; ii < current_num_elmts; ii++) { if (i == off_proc_i[ii]) { off_proc_i[ii] = -1; cancel_indx++; } } hypre_AuxParVectorCancelIndx(aux_vector) = cancel_indx; } /* if elements outside processor boundaries, search for previous occurrences and cancel them */ /* if elements outside processor boundaries, store in off processor stash */ /*if (!max_off_proc_elmts) { max_off_proc_elmts = 100; hypre_AuxParVectorMaxOffProcElmts(aux_vector) = max_off_proc_elmts; hypre_AuxParVectorOffProcI(aux_vector) = hypre_CTAlloc(HYPRE_Int,max_off_proc_elmts); hypre_AuxParVectorOffProcData(aux_vector) = hypre_CTAlloc(double,max_off_proc_elmts); off_proc_i = hypre_AuxParVectorOffProcI(aux_vector); off_proc_data = hypre_AuxParVectorOffProcData(aux_vector); } else if (current_num_elmts + 1 > max_off_proc_elmts) { max_off_proc_elmts += 10; off_proc_i = hypre_TReAlloc(off_proc_i,HYPRE_Int,max_off_proc_elmts); off_proc_data = hypre_TReAlloc(off_proc_data,double, max_off_proc_elmts); hypre_AuxParVectorMaxOffProcElmts(aux_vector) = max_off_proc_elmts; hypre_AuxParVectorOffProcI(aux_vector) = off_proc_i; hypre_AuxParVectorOffProcData(aux_vector) = off_proc_data; } off_proc_i[current_num_elmts] = i; off_proc_data[current_num_elmts++] = values[j]; hypre_AuxParVectorCurrentNumElmts(aux_vector)=current_num_elmts; }*/ else /* local values are inserted into the vector */ { i -= vec_start; data[i] = values[j]; } } } else { if (num_values > vec_stop - vec_start + 1) { if (print_level) { hypre_printf("Warning! Indices beyond local range not identified!\n "); hypre_printf("Off processor values have been ignored!\n"); } num_values = vec_stop - vec_start +1; } for (j = 0; j < num_values; j++) data[j] = values[j]; } return hypre_error_flag; }
/****************************************************************************** * * hypre_IJVectorZeroValuesPar * * zeroes all local components of an IJVectorPar * *****************************************************************************/ HYPRE_Int hypre_IJVectorZeroValuesPar(hypre_IJVector *vector) { HYPRE_Int my_id; HYPRE_Int i, vec_start, vec_stop; double *data; hypre_ParVector *par_vector = hypre_IJVectorObject(vector); MPI_Comm comm = hypre_IJVectorComm(vector); HYPRE_Int *partitioning = hypre_ParVectorPartitioning(par_vector); hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector); HYPRE_Int print_level = hypre_IJVectorPrintLevel(vector); hypre_MPI_Comm_rank(comm, &my_id); /* If par_vector == NULL or partitioning == NULL or local_vector == NULL let user know of catastrophe and exit */ if (!par_vector) { if (print_level) { hypre_printf("par_vector == NULL -- "); hypre_printf("hypre_IJVectorZeroValuesPar\n"); hypre_printf("**** Vector storage is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } if (!partitioning) { if (print_level) { hypre_printf("partitioning == NULL -- "); hypre_printf("hypre_IJVectorZeroValuesPar\n"); hypre_printf("**** Vector partitioning is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } if (!local_vector) { if (print_level) { hypre_printf("local_vector == NULL -- "); hypre_printf("hypre_IJVectorZeroValuesPar\n"); hypre_printf("**** Vector local data is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } #ifdef HYPRE_NO_GLOBAL_PARTITION vec_start = partitioning[0]; vec_stop = partitioning[1]; #else vec_start = partitioning[my_id]; vec_stop = partitioning[my_id+1]; #endif if (vec_start > vec_stop) { if (print_level) { hypre_printf("vec_start > vec_stop -- "); hypre_printf("hypre_IJVectorZeroValuesPar\n"); hypre_printf("**** This vector partitioning should not occur ****\n"); } hypre_error_in_arg(1); } data = hypre_VectorData( local_vector ); for (i = 0; i < vec_stop - vec_start; i++) data[i] = 0.; return hypre_error_flag; }
//======================================================= EpetraExt_HypreIJMatrix::EpetraExt_HypreIJMatrix(HYPRE_IJMatrix matrix) : Epetra_BasicRowMatrix(Epetra_MpiComm(hypre_IJMatrixComm(matrix))), Matrix_(matrix), ParMatrix_(0), NumMyRows_(-1), NumGlobalRows_(-1), NumGlobalCols_(-1), MyRowStart_(-1), MyRowEnd_(-1), MatType_(-1), TransposeSolve_(false), SolveOrPrec_(Solver) { IsSolverSetup_ = new bool[1]; IsPrecondSetup_ = new bool[1]; IsSolverSetup_[0] = false; IsPrecondSetup_[0] = false; // Initialize default values for global variables int ierr = 0; ierr += InitializeDefaults(); TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error, "Couldn't initialize default values."); // Create array of global row ids Teuchos::Array<int> GlobalRowIDs; GlobalRowIDs.resize(NumMyRows_); for (int i = MyRowStart_; i <= MyRowEnd_; i++) { GlobalRowIDs[i-MyRowStart_] = i; } // Create array of global column ids int new_value = 0; int entries = 0; std::set<int> Columns; int num_entries; double *values; int *indices; for(int i = 0; i < NumMyRows_; i++){ ierr += HYPRE_ParCSRMatrixGetRow(ParMatrix_, i+MyRowStart_, &num_entries, &indices, &values); ierr += HYPRE_ParCSRMatrixRestoreRow(ParMatrix_, i+MyRowStart_,&num_entries,&indices,&values); TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error, "Couldn't get row of matrix."); entries = num_entries; for(int j = 0; j < num_entries; j++){ // Insert column ids from this row into set new_value = indices[j]; Columns.insert(new_value); } } int NumMyCols = Columns.size(); Teuchos::Array<int> GlobalColIDs; GlobalColIDs.resize(NumMyCols); std::set<int>::iterator it; int counter = 0; for (it = Columns.begin(); it != Columns.end(); it++) { // Get column ids in order GlobalColIDs[counter] = *it; counter = counter + 1; } //printf("Proc[%d] Rows from %d to %d, num = %d\n", Comm().MyPID(), MyRowStart_,MyRowEnd_, NumMyRows_); Epetra_Map RowMap(-1, NumMyRows_, &GlobalRowIDs[0], 0, Comm()); Epetra_Map ColMap(-1, NumMyCols, &GlobalColIDs[0], 0, Comm()); //Need to call SetMaps() SetMaps(RowMap, ColMap); // Get an MPI_Comm to create vectors. // The vectors will be reused in Multiply(), so that they aren't recreated every time. MPI_Comm comm; ierr += HYPRE_ParCSRMatrixGetComm(ParMatrix_, &comm); TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error, "Couldn't get communicator from Hypre Matrix."); ierr += HYPRE_IJVectorCreate(comm, MyRowStart_, MyRowEnd_, &X_hypre); ierr += HYPRE_IJVectorSetObjectType(X_hypre, HYPRE_PARCSR); ierr += HYPRE_IJVectorInitialize(X_hypre); ierr += HYPRE_IJVectorAssemble(X_hypre); ierr += HYPRE_IJVectorGetObject(X_hypre, (void**) &par_x); TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error, "Couldn't create Hypre X vector."); ierr += HYPRE_IJVectorCreate(comm, MyRowStart_, MyRowEnd_, &Y_hypre); ierr += HYPRE_IJVectorSetObjectType(Y_hypre, HYPRE_PARCSR); ierr += HYPRE_IJVectorInitialize(Y_hypre); ierr += HYPRE_IJVectorAssemble(Y_hypre); ierr += HYPRE_IJVectorGetObject(Y_hypre, (void**) &par_y); TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, std::logic_error, "Couldn't create Hypre Y vector."); x_vec = (hypre_ParVector *) hypre_IJVectorObject(((hypre_IJVector *) X_hypre)); x_local = hypre_ParVectorLocalVector(x_vec); y_vec = (hypre_ParVector *) hypre_IJVectorObject(((hypre_IJVector *) Y_hypre)); y_local = hypre_ParVectorLocalVector(y_vec); SolverCreatePtr_ = &EpetraExt_HypreIJMatrix::Hypre_ParCSRPCGCreate; SolverDestroyPtr_ = &HYPRE_ParCSRPCGDestroy; SolverSetupPtr_ = &HYPRE_ParCSRPCGSetup; SolverSolvePtr_ = &HYPRE_ParCSRPCGSolve; SolverPrecondPtr_ = &HYPRE_ParCSRPCGSetPrecond; CreateSolver(); PrecondCreatePtr_ = &EpetraExt_HypreIJMatrix::Hypre_EuclidCreate; PrecondDestroyPtr_ = &HYPRE_EuclidDestroy; PrecondSetupPtr_ = &HYPRE_EuclidSetup; PrecondSolvePtr_ = &HYPRE_EuclidSolve; CreatePrecond(); ComputeNumericConstants(); ComputeStructureConstants(); } //EpetraExt_HYPREIJMatrix(Hypre_IJMatrix) Constructor
int HYPRE_IJVectorCreate( MPI_Comm comm, HYPRE_BigInt jlower, HYPRE_BigInt jupper, HYPRE_IJVector *vector ) { hypre_IJVector *vec; int num_procs, my_id; HYPRE_BigInt *partitioning; #ifdef HYPRE_NO_GLOBAL_PARTITION HYPRE_BigInt row0, rowN; #else HYPRE_BigInt *recv_buf; HYPRE_BigInt *info; int i, i2; #endif vec = hypre_CTAlloc(hypre_IJVector, 1); if (!vec) { printf("Out of memory -- HYPRE_IJVectorCreate\n"); hypre_error(HYPRE_ERROR_MEMORY); return hypre_error_flag; } MPI_Comm_size(comm, &num_procs); MPI_Comm_rank(comm, &my_id); if (jlower > jupper+1 || jlower < 0) { hypre_error_in_arg(2); return hypre_error_flag; } if (jupper < -1) { hypre_error_in_arg(3); return hypre_error_flag; } #ifdef HYPRE_NO_GLOBAL_PARTITION partitioning = hypre_CTAlloc(HYPRE_BigInt, 2); partitioning[0] = jlower; partitioning[1] = jupper+1; /* now we need the global number of rows as well as the global first row index */ /* proc 0 has the first row */ if (my_id==0) { row0 = jlower; } MPI_Bcast(&row0, 1, MPI_HYPRE_BIG_INT, 0, comm); /* proc (num_procs-1) has the last row */ if (my_id == (num_procs-1)) { rowN = jupper; } MPI_Bcast(&rowN, 1, MPI_HYPRE_BIG_INT, num_procs-1, comm); hypre_IJVectorGlobalFirstRow(vec) = row0; hypre_IJVectorGlobalNumRows(vec) = rowN - row0 + 1; #else info = hypre_CTAlloc(HYPRE_BigInt,2); recv_buf = hypre_CTAlloc(HYPRE_BigInt, 2*num_procs); partitioning = hypre_CTAlloc(HYPRE_BigInt, num_procs+1); info[0] = jlower; info[1] = jupper; MPI_Allgather(info, 2, MPI_HYPRE_BIG_INT, recv_buf, 2, MPI_HYPRE_BIG_INT, comm); partitioning[0] = recv_buf[0]; for (i=0; i < num_procs-1; i++) { i2 = i+i; if (recv_buf[i2+1] != (recv_buf[i2+2]-1)) { printf("Inconsistent partitioning -- HYPRE_IJVectorCreate\n"); hypre_error(HYPRE_ERROR_GENERIC); return hypre_error_flag; } else partitioning[i+1] = recv_buf[i2+2]; } i2 = (num_procs-1)*2; partitioning[num_procs] = recv_buf[i2+1]+1; hypre_TFree(info); hypre_TFree(recv_buf); hypre_IJVectorGlobalFirstRow(vec) = partitioning[0]; hypre_IJVectorGlobalNumRows(vec)= partitioning[num_procs]-partitioning[0]; #endif hypre_IJVectorComm(vec) = comm; hypre_IJVectorPartitioning(vec) = partitioning; hypre_IJVectorObjectType(vec) = HYPRE_UNITIALIZED; hypre_IJVectorObject(vec) = NULL; hypre_IJVectorTranslator(vec) = NULL; *vector = (HYPRE_IJVector) vec; return hypre_error_flag; }