added a switch to allow for agglomeration instead of redundant coarse grid solve.
Redundant coarse grid solve now requires additional call to HYPRE_BoomerAMGSetRedundant.
This commit is contained in:
parent
e893e88937
commit
684df1fce4
@ -174,6 +174,24 @@ HYPRE_BoomerAMGGetSeqThreshold( HYPRE_Solver solver,
|
||||
return( hypre_BoomerAMGGetSeqThreshold( (void *) solver, seq_threshold ) );
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* HYPRE_BoomerAMGSetRedundant, HYPRE_BoomerAMGGetRedundant
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
HYPRE_Int
|
||||
HYPRE_BoomerAMGSetRedundant( HYPRE_Solver solver,
|
||||
HYPRE_Int redundant )
|
||||
{
|
||||
return( hypre_BoomerAMGSetRedundant( (void *) solver, redundant ) );
|
||||
}
|
||||
|
||||
HYPRE_Int
|
||||
HYPRE_BoomerAMGGetRedundant( HYPRE_Solver solver,
|
||||
HYPRE_Int * redundant )
|
||||
{
|
||||
return( hypre_BoomerAMGGetRedundant( (void *) solver, redundant ) );
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* HYPRE_BoomerAMGSetStrongThreshold, HYPRE_BoomerAMGGetStrongThreshold
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
@ -176,12 +176,18 @@ HYPRE_Int HYPRE_BoomerAMGSetMinCoarseSize(HYPRE_Solver solver,
|
||||
HYPRE_Int min_coarse_size);
|
||||
|
||||
/**
|
||||
* (Optional) Sets maximal size for redundant coarse grid solve.
|
||||
* (Optional) Sets maximal size for agglomeration or redundant coarse grid solve.
|
||||
* When the system is smaller than this threshold, sequential AMG is used
|
||||
* on all remaining active processors.
|
||||
* on process 0 or on all remaining active processes (if redundant = 1 ).
|
||||
**/
|
||||
HYPRE_Int HYPRE_BoomerAMGSetSeqThreshold(HYPRE_Solver solver,
|
||||
HYPRE_Int seq_threshold);
|
||||
/**
|
||||
* (Optional) operates switch for redundancy. Needs to be used with
|
||||
* HYPRE_BoomerAMGSetSeqThreshold. Default is 0, i.e. no redundancy.
|
||||
**/
|
||||
HYPRE_Int HYPRE_BoomerAMGSetRedundant(HYPRE_Solver solver,
|
||||
HYPRE_Int redundant);
|
||||
|
||||
/**
|
||||
* (Optional) Sets AMG strength threshold. The default is 0.25.
|
||||
|
||||
@ -91,6 +91,8 @@ typedef struct
|
||||
HYPRE_Int max_coarse_size;
|
||||
HYPRE_Int min_coarse_size;
|
||||
HYPRE_Int seq_threshold;
|
||||
HYPRE_Int redundant;
|
||||
HYPRE_Int participate;
|
||||
|
||||
/* solve params */
|
||||
HYPRE_Int max_iter;
|
||||
@ -401,6 +403,8 @@ typedef struct
|
||||
#define hypre_ParAMGDataFCoarse(amg_data) ((amg_data)->f_coarse)
|
||||
#define hypre_ParAMGDataUCoarse(amg_data) ((amg_data)->u_coarse)
|
||||
#define hypre_ParAMGDataNewComm(amg_data) ((amg_data)->new_comm)
|
||||
#define hypre_ParAMGDataRedundant(amg_data) ((amg_data)->redundant)
|
||||
#define hypre_ParAMGDataParticipate(amg_data) ((amg_data)->participate)
|
||||
|
||||
#define hypre_ParAMGDataAMat(amg_data) ((amg_data)->A_mat)
|
||||
#define hypre_ParAMGDataBVec(amg_data) ((amg_data)->b_vec)
|
||||
@ -668,6 +672,8 @@ HYPRE_Int HYPRE_BoomerAMGSetMinCoarseSize ( HYPRE_Solver solver , HYPRE_Int min_
|
||||
HYPRE_Int HYPRE_BoomerAMGGetMinCoarseSize ( HYPRE_Solver solver , HYPRE_Int *min_coarse_size );
|
||||
HYPRE_Int HYPRE_BoomerAMGSetSeqThreshold ( HYPRE_Solver solver , HYPRE_Int seq_threshold );
|
||||
HYPRE_Int HYPRE_BoomerAMGGetSeqThreshold ( HYPRE_Solver solver , HYPRE_Int *seq_threshold );
|
||||
HYPRE_Int HYPRE_BoomerAMGSetRedundant ( HYPRE_Solver solver , HYPRE_Int redundant );
|
||||
HYPRE_Int HYPRE_BoomerAMGGetRedundant ( HYPRE_Solver solver , HYPRE_Int *redundant );
|
||||
HYPRE_Int HYPRE_BoomerAMGSetStrongThreshold ( HYPRE_Solver solver , double strong_threshold );
|
||||
HYPRE_Int HYPRE_BoomerAMGGetStrongThreshold ( HYPRE_Solver solver , double *strong_threshold );
|
||||
HYPRE_Int HYPRE_BoomerAMGSetMaxRowSum ( HYPRE_Solver solver , double max_row_sum );
|
||||
@ -1052,6 +1058,8 @@ HYPRE_Int hypre_BoomerAMGSetMinCoarseSize ( void *data , HYPRE_Int min_coarse_si
|
||||
HYPRE_Int hypre_BoomerAMGGetMinCoarseSize ( void *data , HYPRE_Int *min_coarse_size );
|
||||
HYPRE_Int hypre_BoomerAMGSetSeqThreshold ( void *data , HYPRE_Int seq_threshold );
|
||||
HYPRE_Int hypre_BoomerAMGGetSeqThreshold ( void *data , HYPRE_Int *seq_threshold );
|
||||
HYPRE_Int hypre_BoomerAMGSetRedundant ( void *data , HYPRE_Int redundant );
|
||||
HYPRE_Int hypre_BoomerAMGGetRedundant ( void *data , HYPRE_Int *redundant );
|
||||
HYPRE_Int hypre_BoomerAMGSetStrongThreshold ( void *data , double strong_threshold );
|
||||
HYPRE_Int hypre_BoomerAMGGetStrongThreshold ( void *data , double *strong_threshold );
|
||||
HYPRE_Int hypre_BoomerAMGSetMaxRowSum ( void *data , double max_row_sum );
|
||||
|
||||
@ -25,7 +25,7 @@ HYPRE_Int hypre_seqAMGSetup( hypre_ParAMGData *amg_data,
|
||||
hypre_CSRMatrix *A_seq_offd;
|
||||
hypre_ParVector *F_seq = NULL;
|
||||
hypre_ParVector *U_seq = NULL;
|
||||
|
||||
|
||||
hypre_ParCSRMatrix *A;
|
||||
|
||||
HYPRE_Int **dof_func_array;
|
||||
@ -33,15 +33,16 @@ HYPRE_Int hypre_seqAMGSetup( hypre_ParAMGData *amg_data,
|
||||
|
||||
HYPRE_Int not_finished_coarsening;
|
||||
HYPRE_Int level;
|
||||
HYPRE_Int redundant;
|
||||
|
||||
HYPRE_Solver coarse_solver;
|
||||
|
||||
/* misc */
|
||||
dof_func_array = hypre_ParAMGDataDofFuncArray(amg_data);
|
||||
redundant = hypre_ParAMGDataRedundant(amg_data);
|
||||
|
||||
/*MPI Stuff */
|
||||
hypre_MPI_Comm_size(comm, &num_procs);
|
||||
hypre_MPI_Comm_rank(comm,&my_id);
|
||||
|
||||
/*initial */
|
||||
level = p_level;
|
||||
@ -61,7 +62,9 @@ HYPRE_Int hypre_seqAMGSetup( hypre_ParAMGData *amg_data,
|
||||
HYPRE_Int *A_tmp_i = NULL;
|
||||
HYPRE_Int *A_tmp_j = NULL;
|
||||
|
||||
HYPRE_Int *info, *displs, *displs2;
|
||||
HYPRE_Int *info = NULL;
|
||||
HYPRE_Int *displs = NULL;
|
||||
HYPRE_Int *displs2 = NULL;
|
||||
HYPRE_Int i, j, size, num_nonzeros, total_nnz, cnt;
|
||||
|
||||
hypre_CSRMatrix *A_diag = hypre_ParCSRMatrixDiag(A);
|
||||
@ -105,39 +108,47 @@ HYPRE_Int hypre_seqAMGSetup( hypre_ParAMGData *amg_data,
|
||||
|
||||
if (num_rows)
|
||||
{
|
||||
hypre_ParAMGDataParticipate(amg_data) = 1;
|
||||
hypre_MPI_Comm_size(new_comm, &new_num_procs);
|
||||
hypre_MPI_Comm_rank(new_comm, &my_id);
|
||||
info = hypre_CTAlloc(HYPRE_Int, new_num_procs);
|
||||
|
||||
hypre_MPI_Allgather(&num_rows, 1, HYPRE_MPI_INT, info, 1, HYPRE_MPI_INT, new_comm);
|
||||
if (redundant)
|
||||
hypre_MPI_Allgather(&num_rows, 1, HYPRE_MPI_INT, info, 1, HYPRE_MPI_INT, new_comm);
|
||||
else
|
||||
hypre_MPI_Gather(&num_rows, 1, HYPRE_MPI_INT, info, 1, HYPRE_MPI_INT, 0, new_comm);
|
||||
|
||||
/* alloc space in seq data structure only for participating procs*/
|
||||
HYPRE_BoomerAMGCreate(&coarse_solver);
|
||||
HYPRE_BoomerAMGSetMaxRowSum(coarse_solver,
|
||||
if (redundant || my_id == 0)
|
||||
{
|
||||
HYPRE_BoomerAMGCreate(&coarse_solver);
|
||||
HYPRE_BoomerAMGSetMaxRowSum(coarse_solver,
|
||||
hypre_ParAMGDataMaxRowSum(amg_data));
|
||||
HYPRE_BoomerAMGSetStrongThreshold(coarse_solver,
|
||||
HYPRE_BoomerAMGSetStrongThreshold(coarse_solver,
|
||||
hypre_ParAMGDataStrongThreshold(amg_data));
|
||||
HYPRE_BoomerAMGSetCoarsenType(coarse_solver,
|
||||
HYPRE_BoomerAMGSetCoarsenType(coarse_solver,
|
||||
hypre_ParAMGDataCoarsenType(amg_data));
|
||||
HYPRE_BoomerAMGSetInterpType(coarse_solver,
|
||||
HYPRE_BoomerAMGSetInterpType(coarse_solver,
|
||||
hypre_ParAMGDataInterpType(amg_data));
|
||||
HYPRE_BoomerAMGSetTruncFactor(coarse_solver,
|
||||
HYPRE_BoomerAMGSetTruncFactor(coarse_solver,
|
||||
hypre_ParAMGDataTruncFactor(amg_data));
|
||||
HYPRE_BoomerAMGSetPMaxElmts(coarse_solver,
|
||||
HYPRE_BoomerAMGSetPMaxElmts(coarse_solver,
|
||||
hypre_ParAMGDataPMaxElmts(amg_data));
|
||||
if (hypre_ParAMGDataUserRelaxType(amg_data) > -1)
|
||||
HYPRE_BoomerAMGSetRelaxType(coarse_solver,
|
||||
if (hypre_ParAMGDataUserRelaxType(amg_data) > -1)
|
||||
HYPRE_BoomerAMGSetRelaxType(coarse_solver,
|
||||
hypre_ParAMGDataUserRelaxType(amg_data));
|
||||
HYPRE_BoomerAMGSetRelaxOrder(coarse_solver,
|
||||
HYPRE_BoomerAMGSetRelaxOrder(coarse_solver,
|
||||
hypre_ParAMGDataRelaxOrder(amg_data));
|
||||
HYPRE_BoomerAMGSetRelaxWt(coarse_solver,
|
||||
HYPRE_BoomerAMGSetRelaxWt(coarse_solver,
|
||||
hypre_ParAMGDataUserRelaxWeight(amg_data));
|
||||
if (hypre_ParAMGDataUserNumSweeps(amg_data) > -1)
|
||||
HYPRE_BoomerAMGSetNumSweeps(coarse_solver,
|
||||
if (hypre_ParAMGDataUserNumSweeps(amg_data) > -1)
|
||||
HYPRE_BoomerAMGSetNumSweeps(coarse_solver,
|
||||
hypre_ParAMGDataUserNumSweeps(amg_data));
|
||||
HYPRE_BoomerAMGSetNumFunctions(coarse_solver,
|
||||
HYPRE_BoomerAMGSetNumFunctions(coarse_solver,
|
||||
hypre_ParAMGDataNumFunctions(amg_data));
|
||||
HYPRE_BoomerAMGSetMaxIter(coarse_solver, 1);
|
||||
HYPRE_BoomerAMGSetTol(coarse_solver, 0);
|
||||
HYPRE_BoomerAMGSetMaxIter(coarse_solver, 1);
|
||||
HYPRE_BoomerAMGSetTol(coarse_solver, 0);
|
||||
}
|
||||
|
||||
/* Create CSR Matrix, will be Diag part of new matrix */
|
||||
A_tmp_i = hypre_CTAlloc(HYPRE_Int, num_rows+1);
|
||||
@ -172,91 +183,113 @@ HYPRE_Int hypre_seqAMGSetup( hypre_ParAMGData *amg_data,
|
||||
displs[i] = displs[i-1]+info[i-1];
|
||||
size = displs[new_num_procs];
|
||||
|
||||
A_seq_i = hypre_CTAlloc(HYPRE_Int, size+1);
|
||||
A_seq_offd_i = hypre_CTAlloc(HYPRE_Int, size+1);
|
||||
|
||||
hypre_MPI_Allgatherv ( &A_tmp_i[1], num_rows, HYPRE_MPI_INT, &A_seq_i[1], info,
|
||||
displs, HYPRE_MPI_INT, new_comm );
|
||||
|
||||
displs2 = hypre_CTAlloc(HYPRE_Int, new_num_procs+1);
|
||||
|
||||
A_seq_i[0] = 0;
|
||||
displs2[0] = 0;
|
||||
for (j=1; j < displs[1]; j++)
|
||||
A_seq_i[j] = A_seq_i[j]+A_seq_i[j-1];
|
||||
for (i=1; i < new_num_procs; i++)
|
||||
if (redundant || my_id == 0)
|
||||
{
|
||||
for (j=displs[i]; j < displs[i+1]; j++)
|
||||
{
|
||||
A_seq_i = hypre_CTAlloc(HYPRE_Int, size+1);
|
||||
A_seq_offd_i = hypre_CTAlloc(HYPRE_Int, size+1);
|
||||
}
|
||||
|
||||
if (redundant)
|
||||
hypre_MPI_Allgatherv ( &A_tmp_i[1], num_rows, HYPRE_MPI_INT, &A_seq_i[1], info,
|
||||
displs, HYPRE_MPI_INT, new_comm );
|
||||
else
|
||||
hypre_MPI_Gatherv ( &A_tmp_i[1], num_rows, HYPRE_MPI_INT, &A_seq_i[1], info,
|
||||
displs, HYPRE_MPI_INT, 0, new_comm );
|
||||
|
||||
if (redundant || my_id == 0)
|
||||
{
|
||||
displs2 = hypre_CTAlloc(HYPRE_Int, new_num_procs+1);
|
||||
|
||||
A_seq_i[0] = 0;
|
||||
displs2[0] = 0;
|
||||
for (j=1; j < displs[1]; j++)
|
||||
A_seq_i[j] = A_seq_i[j]+A_seq_i[j-1];
|
||||
for (i=1; i < new_num_procs; i++)
|
||||
{
|
||||
for (j=displs[i]; j < displs[i+1]; j++)
|
||||
{
|
||||
A_seq_i[j] = A_seq_i[j]+A_seq_i[j-1];
|
||||
}
|
||||
}
|
||||
A_seq_i[size] = A_seq_i[size]+A_seq_i[size-1];
|
||||
displs2[new_num_procs] = A_seq_i[size];
|
||||
for (i=1; i < new_num_procs+1; i++)
|
||||
{
|
||||
displs2[i] = A_seq_i[displs[i]];
|
||||
info[i-1] = displs2[i] - displs2[i-1];
|
||||
}
|
||||
|
||||
total_nnz = displs2[new_num_procs];
|
||||
A_seq_j = hypre_CTAlloc(HYPRE_Int, total_nnz);
|
||||
A_seq_data = hypre_CTAlloc(double, total_nnz);
|
||||
}
|
||||
A_seq_i[size] = A_seq_i[size]+A_seq_i[size-1];
|
||||
displs2[new_num_procs] = A_seq_i[size];
|
||||
for (i=1; i < new_num_procs+1; i++)
|
||||
if (redundant)
|
||||
{
|
||||
displs2[i] = A_seq_i[displs[i]];
|
||||
info[i-1] = displs2[i] - displs2[i-1];
|
||||
}
|
||||
|
||||
total_nnz = displs2[new_num_procs];
|
||||
A_seq_j = hypre_CTAlloc(HYPRE_Int, total_nnz);
|
||||
A_seq_data = hypre_CTAlloc(double, total_nnz);
|
||||
|
||||
hypre_MPI_Allgatherv ( A_tmp_j, num_nonzeros, HYPRE_MPI_INT,
|
||||
hypre_MPI_Allgatherv ( A_tmp_j, num_nonzeros, HYPRE_MPI_INT,
|
||||
A_seq_j, info, displs2,
|
||||
HYPRE_MPI_INT, new_comm );
|
||||
|
||||
hypre_MPI_Allgatherv ( A_tmp_data, num_nonzeros, hypre_MPI_DOUBLE,
|
||||
hypre_MPI_Allgatherv ( A_tmp_data, num_nonzeros, hypre_MPI_DOUBLE,
|
||||
A_seq_data, info, displs2,
|
||||
hypre_MPI_DOUBLE, new_comm );
|
||||
}
|
||||
else
|
||||
{
|
||||
hypre_MPI_Gatherv ( A_tmp_j, num_nonzeros, HYPRE_MPI_INT,
|
||||
A_seq_j, info, displs2,
|
||||
HYPRE_MPI_INT, 0, new_comm );
|
||||
|
||||
hypre_TFree(info);
|
||||
hypre_TFree(displs);
|
||||
hypre_TFree(displs2);
|
||||
hypre_TFree(A_tmp_i);
|
||||
hypre_TFree(A_tmp_j);
|
||||
hypre_TFree(A_tmp_data);
|
||||
hypre_MPI_Gatherv ( A_tmp_data, num_nonzeros, hypre_MPI_DOUBLE,
|
||||
A_seq_data, info, displs2,
|
||||
hypre_MPI_DOUBLE, 0, new_comm );
|
||||
}
|
||||
|
||||
if (redundant || my_id == 0)
|
||||
{
|
||||
hypre_TFree(info);
|
||||
hypre_TFree(displs);
|
||||
hypre_TFree(displs2);
|
||||
hypre_TFree(A_tmp_i);
|
||||
hypre_TFree(A_tmp_j);
|
||||
hypre_TFree(A_tmp_data);
|
||||
|
||||
row_starts = hypre_CTAlloc(HYPRE_Int,2);
|
||||
row_starts[0] = 0;
|
||||
row_starts[1] = size;
|
||||
row_starts = hypre_CTAlloc(HYPRE_Int,2);
|
||||
row_starts[0] = 0;
|
||||
row_starts[1] = size;
|
||||
|
||||
/* Create 1 proc communicator */
|
||||
seq_comm = hypre_MPI_COMM_SELF;
|
||||
/* Create 1 proc communicator */
|
||||
seq_comm = hypre_MPI_COMM_SELF;
|
||||
|
||||
A_seq = hypre_ParCSRMatrixCreate(seq_comm,size,size,
|
||||
A_seq = hypre_ParCSRMatrixCreate(seq_comm,size,size,
|
||||
row_starts, row_starts,
|
||||
0,total_nnz,0);
|
||||
|
||||
A_seq_diag = hypre_ParCSRMatrixDiag(A_seq);
|
||||
A_seq_offd = hypre_ParCSRMatrixOffd(A_seq);
|
||||
A_seq_diag = hypre_ParCSRMatrixDiag(A_seq);
|
||||
A_seq_offd = hypre_ParCSRMatrixOffd(A_seq);
|
||||
|
||||
hypre_CSRMatrixData(A_seq_diag) = A_seq_data;
|
||||
hypre_CSRMatrixI(A_seq_diag) = A_seq_i;
|
||||
hypre_CSRMatrixJ(A_seq_diag) = A_seq_j;
|
||||
hypre_CSRMatrixI(A_seq_offd) = A_seq_offd_i;
|
||||
hypre_CSRMatrixData(A_seq_diag) = A_seq_data;
|
||||
hypre_CSRMatrixI(A_seq_diag) = A_seq_i;
|
||||
hypre_CSRMatrixJ(A_seq_diag) = A_seq_j;
|
||||
hypre_CSRMatrixI(A_seq_offd) = A_seq_offd_i;
|
||||
|
||||
F_seq = hypre_ParVectorCreate(seq_comm, size, row_starts);
|
||||
U_seq = hypre_ParVectorCreate(seq_comm, size, row_starts);
|
||||
hypre_ParVectorOwnsPartitioning(F_seq) = 0;
|
||||
hypre_ParVectorOwnsPartitioning(U_seq) = 0;
|
||||
hypre_ParVectorInitialize(F_seq);
|
||||
hypre_ParVectorInitialize(U_seq);
|
||||
F_seq = hypre_ParVectorCreate(seq_comm, size, row_starts);
|
||||
U_seq = hypre_ParVectorCreate(seq_comm, size, row_starts);
|
||||
hypre_ParVectorOwnsPartitioning(F_seq) = 0;
|
||||
hypre_ParVectorOwnsPartitioning(U_seq) = 0;
|
||||
hypre_ParVectorInitialize(F_seq);
|
||||
hypre_ParVectorInitialize(U_seq);
|
||||
|
||||
hypre_BoomerAMGSetup(coarse_solver,A_seq,F_seq,U_seq);
|
||||
hypre_BoomerAMGSetup(coarse_solver,A_seq,F_seq,U_seq);
|
||||
|
||||
hypre_ParAMGDataCoarseSolver(amg_data) = coarse_solver;
|
||||
hypre_ParAMGDataACoarse(amg_data) = A_seq;
|
||||
hypre_ParAMGDataFCoarse(amg_data) = F_seq;
|
||||
hypre_ParAMGDataUCoarse(amg_data) = U_seq;
|
||||
hypre_ParAMGDataCoarseSolver(amg_data) = coarse_solver;
|
||||
hypre_ParAMGDataACoarse(amg_data) = A_seq;
|
||||
hypre_ParAMGDataFCoarse(amg_data) = F_seq;
|
||||
hypre_ParAMGDataUCoarse(amg_data) = U_seq;
|
||||
}
|
||||
hypre_ParAMGDataNewComm(amg_data) = new_comm;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -293,6 +326,7 @@ hypre_seqAMGCycle( hypre_ParAMGData *amg_data,
|
||||
hypre_ParCSRMatrix *A_coarse = hypre_ParAMGDataACoarse(amg_data);
|
||||
hypre_ParVector *F_coarse = hypre_ParAMGDataFCoarse(amg_data);
|
||||
hypre_ParVector *U_coarse = hypre_ParAMGDataUCoarse(amg_data);
|
||||
HYPRE_Int redundant = hypre_ParAMGDataRedundant(amg_data);
|
||||
|
||||
Aux_U = Par_U_array[p_level];
|
||||
Aux_F = Par_F_array[p_level];
|
||||
@ -303,7 +337,8 @@ hypre_seqAMGCycle( hypre_ParAMGData *amg_data,
|
||||
n = hypre_VectorSize(u_local);
|
||||
|
||||
|
||||
if (A_coarse)
|
||||
/*if (A_coarse)*/
|
||||
if (hypre_ParAMGDataParticipate(amg_data))
|
||||
{
|
||||
double *f_data;
|
||||
hypre_Vector *f_local;
|
||||
@ -312,11 +347,13 @@ hypre_seqAMGCycle( hypre_ParAMGData *amg_data,
|
||||
HYPRE_Int nf;
|
||||
HYPRE_Int local_info;
|
||||
double *recv_buf;
|
||||
HYPRE_Int *displs, *info;
|
||||
HYPRE_Int *displs = NULL;
|
||||
HYPRE_Int *info = NULL;
|
||||
HYPRE_Int size;
|
||||
HYPRE_Int new_num_procs;
|
||||
HYPRE_Int new_num_procs, my_id;
|
||||
|
||||
hypre_MPI_Comm_size(new_comm, &new_num_procs);
|
||||
hypre_MPI_Comm_rank(new_comm, &my_id);
|
||||
|
||||
f_local = hypre_ParVectorLocalVector(Aux_F);
|
||||
f_data = hypre_VectorData(f_local);
|
||||
@ -325,36 +362,60 @@ hypre_seqAMGCycle( hypre_ParAMGData *amg_data,
|
||||
/* first f */
|
||||
info = hypre_CTAlloc(HYPRE_Int, new_num_procs);
|
||||
local_info = nf;
|
||||
hypre_MPI_Allgather(&local_info, 1, HYPRE_MPI_INT, info, 1, HYPRE_MPI_INT, new_comm);
|
||||
if (redundant)
|
||||
hypre_MPI_Allgather(&local_info, 1, HYPRE_MPI_INT, info, 1, HYPRE_MPI_INT, new_comm);
|
||||
else
|
||||
hypre_MPI_Gather(&local_info, 1, HYPRE_MPI_INT, info, 1, HYPRE_MPI_INT, 0, new_comm);
|
||||
|
||||
displs = hypre_CTAlloc(HYPRE_Int, new_num_procs+1);
|
||||
displs[0] = 0;
|
||||
for (i=1; i < new_num_procs+1; i++)
|
||||
displs[i] = displs[i-1]+info[i-1];
|
||||
size = displs[new_num_procs];
|
||||
if (redundant || my_id ==0)
|
||||
{
|
||||
displs = hypre_CTAlloc(HYPRE_Int, new_num_procs+1);
|
||||
displs[0] = 0;
|
||||
for (i=1; i < new_num_procs+1; i++)
|
||||
displs[i] = displs[i-1]+info[i-1];
|
||||
size = displs[new_num_procs];
|
||||
|
||||
tmp_vec = hypre_ParVectorLocalVector(F_coarse);
|
||||
recv_buf = hypre_VectorData(tmp_vec);
|
||||
tmp_vec = hypre_ParVectorLocalVector(F_coarse);
|
||||
recv_buf = hypre_VectorData(tmp_vec);
|
||||
}
|
||||
|
||||
hypre_MPI_Allgatherv ( f_data, nf, hypre_MPI_DOUBLE,
|
||||
recv_buf, info, displs,
|
||||
if (redundant)
|
||||
hypre_MPI_Allgatherv ( f_data, nf, hypre_MPI_DOUBLE,
|
||||
recv_buf, info, displs,
|
||||
hypre_MPI_DOUBLE, new_comm );
|
||||
else
|
||||
hypre_MPI_Gatherv ( f_data, nf, hypre_MPI_DOUBLE,
|
||||
recv_buf, info, displs,
|
||||
hypre_MPI_DOUBLE, 0, new_comm );
|
||||
|
||||
tmp_vec = hypre_ParVectorLocalVector(U_coarse);
|
||||
recv_buf = hypre_VectorData(tmp_vec);
|
||||
if (redundant || my_id ==0)
|
||||
{
|
||||
tmp_vec = hypre_ParVectorLocalVector(U_coarse);
|
||||
recv_buf = hypre_VectorData(tmp_vec);
|
||||
}
|
||||
|
||||
/*then u */
|
||||
hypre_MPI_Allgatherv ( u_data, n, hypre_MPI_DOUBLE,
|
||||
recv_buf, info, displs,
|
||||
if (redundant)
|
||||
{
|
||||
hypre_MPI_Allgatherv ( u_data, n, hypre_MPI_DOUBLE,
|
||||
recv_buf, info, displs,
|
||||
hypre_MPI_DOUBLE, new_comm );
|
||||
hypre_TFree(displs);
|
||||
hypre_TFree(info);
|
||||
}
|
||||
else
|
||||
hypre_MPI_Gatherv ( u_data, n, hypre_MPI_DOUBLE,
|
||||
recv_buf, info, displs,
|
||||
hypre_MPI_DOUBLE, 0, new_comm );
|
||||
|
||||
/* clean up */
|
||||
hypre_TFree(displs);
|
||||
hypre_TFree(info);
|
||||
|
||||
hypre_BoomerAMGSolve(coarse_solver, A_coarse, F_coarse, U_coarse);
|
||||
if (redundant || my_id ==0)
|
||||
{
|
||||
hypre_BoomerAMGSolve(coarse_solver, A_coarse, F_coarse, U_coarse);
|
||||
}
|
||||
|
||||
/*copy my part of U to parallel vector */
|
||||
if (redundant)
|
||||
{
|
||||
double *local_data;
|
||||
|
||||
@ -365,6 +426,22 @@ hypre_seqAMGCycle( hypre_ParAMGData *amg_data,
|
||||
u_data[i] = local_data[first_index+i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
double *local_data;
|
||||
|
||||
if (my_id == 0)
|
||||
local_data = hypre_VectorData(hypre_ParVectorLocalVector(U_coarse));
|
||||
|
||||
hypre_MPI_Scatterv ( local_data, info, displs, hypre_MPI_DOUBLE,
|
||||
u_data, n, hypre_MPI_DOUBLE, 0, new_comm );
|
||||
/*if (my_id == 0)
|
||||
local_data = hypre_VectorData(hypre_ParVectorLocalVector(F_coarse));
|
||||
MPI_Scatterv ( local_data, info, displs, hypre_MPI_DOUBLE,
|
||||
f_data, n, hypre_MPI_DOUBLE, 0, new_comm );*/
|
||||
if (my_id == 0) hypre_TFree(displs);
|
||||
hypre_TFree(info);
|
||||
}
|
||||
}
|
||||
|
||||
return(Solve_err_flag);
|
||||
|
||||
@ -65,6 +65,8 @@ hypre_BoomerAMGCreate()
|
||||
HYPRE_Int CR_use_CG;
|
||||
HYPRE_Int cgc_its;
|
||||
HYPRE_Int seq_threshold;
|
||||
HYPRE_Int redundant;
|
||||
HYPRE_Int participate;
|
||||
|
||||
/* solve params */
|
||||
HYPRE_Int min_iter;
|
||||
@ -120,6 +122,8 @@ hypre_BoomerAMGCreate()
|
||||
max_coarse_size = 9;
|
||||
min_coarse_size = 0;
|
||||
seq_threshold = 0;
|
||||
redundant = 1;
|
||||
participate = 0;
|
||||
strong_threshold = 0.25;
|
||||
max_row_sum = 0.9;
|
||||
trunc_factor = 0.0;
|
||||
@ -767,6 +771,48 @@ hypre_BoomerAMGGetSeqThreshold( void *data,
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
HYPRE_Int
|
||||
hypre_BoomerAMGSetRedundant( void *data,
|
||||
HYPRE_Int redundant )
|
||||
{
|
||||
hypre_ParAMGData *amg_data = data;
|
||||
|
||||
if (!amg_data)
|
||||
{
|
||||
hypre_printf("Warning! BoomerAMG object empty!\n");
|
||||
hypre_error_in_arg(1);
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
if (redundant < 0)
|
||||
{
|
||||
hypre_error_in_arg(2);
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
hypre_ParAMGDataRedundant(amg_data) = redundant;
|
||||
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
HYPRE_Int
|
||||
hypre_BoomerAMGGetRedundant( void *data,
|
||||
HYPRE_Int * redundant )
|
||||
{
|
||||
hypre_ParAMGData *amg_data = data;
|
||||
|
||||
if (!amg_data)
|
||||
{
|
||||
hypre_printf("Warning! BoomerAMG object empty!\n");
|
||||
hypre_error_in_arg(1);
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
*redundant = hypre_ParAMGDataRedundant(amg_data);
|
||||
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
HYPRE_Int
|
||||
hypre_BoomerAMGSetStrongThreshold( void *data,
|
||||
double strong_threshold )
|
||||
|
||||
@ -60,6 +60,8 @@ typedef struct
|
||||
HYPRE_Int max_coarse_size;
|
||||
HYPRE_Int min_coarse_size;
|
||||
HYPRE_Int seq_threshold;
|
||||
HYPRE_Int redundant;
|
||||
HYPRE_Int participate;
|
||||
|
||||
/* solve params */
|
||||
HYPRE_Int max_iter;
|
||||
@ -370,6 +372,8 @@ typedef struct
|
||||
#define hypre_ParAMGDataFCoarse(amg_data) ((amg_data)->f_coarse)
|
||||
#define hypre_ParAMGDataUCoarse(amg_data) ((amg_data)->u_coarse)
|
||||
#define hypre_ParAMGDataNewComm(amg_data) ((amg_data)->new_comm)
|
||||
#define hypre_ParAMGDataRedundant(amg_data) ((amg_data)->redundant)
|
||||
#define hypre_ParAMGDataParticipate(amg_data) ((amg_data)->participate)
|
||||
|
||||
#define hypre_ParAMGDataAMat(amg_data) ((amg_data)->A_mat)
|
||||
#define hypre_ParAMGDataBVec(amg_data) ((amg_data)->b_vec)
|
||||
|
||||
@ -157,7 +157,7 @@ hypre_BoomerAMGCycle( void *amg_vdata,
|
||||
|
||||
lev_counter = hypre_CTAlloc(HYPRE_Int, num_levels);
|
||||
|
||||
if (hypre_ParAMGDataACoarse(amg_data)) seq_cg = 1;
|
||||
if (hypre_ParAMGDataParticipate(amg_data)) seq_cg = 1;
|
||||
|
||||
/* Initialize */
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user