29 #define moab_hypre_assert( a, b ) \
32 #define moab_hypre_assert_t( a, b ) \
36 std::cout << "HYPRE Error: " << b << std::endl; \
40 HypreSolver::HypreSolver(
bool iterative ) : AbstractSolver( iterative )
47 HypreSolver::HypreSolver( HypreParMatrix* _A,
bool iterative ) : AbstractSolver( iterative )
54 HYPRE_Int HypreSolver::Solve(
const HypreParVector& b, HypreParVector& x )
const
65 err = SetupFcn()( *
this, *A, b.x_par, x.x_par );
74 err = SolveFcn()( *
this, *A, b.x_par, x.x_par );
78 HypreSolver::~HypreSolver()
91 HyprePCG::HyprePCG( HypreParMatrix& _A ) : HypreSolver( &_A, true )
93 iterative_mode =
true;
94 HYPRE_ParCSRPCGCreate( A->GetParallelCommunicator()->comm(), &pcg_solver );
97 void HyprePCG::SetTol(
double tol )
99 HYPRE_PCGSetTol( pcg_solver, tol );
102 void HyprePCG::SetMaxIter(
int max_iter )
104 HYPRE_PCGSetMaxIter( pcg_solver, max_iter );
107 void HyprePCG::SetLogging(
int logging )
109 HYPRE_PCGSetLogging( pcg_solver, logging );
112 void HyprePCG::Verbosity(
int print_lvl )
114 HYPRE_ParCSRPCGSetPrintLevel( pcg_solver, print_lvl );
117 void HyprePCG::SetPreconditioner( HypreSolver& precond )
119 HYPRE_ParCSRPCGSetPrecond( pcg_solver, precond.SolveFcn(), precond.SetupFcn(), precond );
122 void HyprePCG::SetResidualConvergenceOptions(
int res_frequency,
double rtol )
124 HYPRE_PCGSetTwoNorm( pcg_solver, 1 );
126 if( res_frequency > 0 )
128 HYPRE_PCGSetRecomputeResidualP( pcg_solver, res_frequency );
133 HYPRE_PCGSetResidualTol( pcg_solver, rtol );
137 HYPRE_Int HyprePCG::Solve(
const HypreParVector& b, HypreParVector& x )
const
141 HYPRE_Int time_index = 0;
142 HYPRE_Int num_iterations;
143 double final_res_norm;
145 HYPRE_Int print_level;
146 HYPRE_PCGGetPrintLevel( pcg_solver, &print_level );
147 pcomm = A->GetParallelCommunicator();
151 if( print_level > 0 )
154 time_index = hypre_InitializeTiming(
"PCG Setup" );
155 hypre_BeginTiming( time_index );
159 err = HYPRE_ParCSRPCGSetup( pcg_solver, *A, (HYPRE_ParVector)b, (HYPRE_ParVector)x );
164 cout <<
"PCG Setup failed with error = " << err << endl;
168 if( print_level > 0 )
171 hypre_EndTiming( time_index );
172 hypre_PrintTiming(
"Setup phase times", pcomm->
comm() );
173 hypre_FinalizeTiming( time_index );
179 if( print_level > 0 )
182 time_index = hypre_InitializeTiming(
"PCG Solve" );
183 hypre_BeginTiming( time_index );
187 if( !iterative_mode )
192 err = HYPRE_ParCSRPCGSolve( pcg_solver, *A, (HYPRE_ParVector)b, (HYPRE_ParVector)x );
194 if( print_level > 0 )
197 hypre_EndTiming( time_index );
198 hypre_PrintTiming(
"Solve phase times", pcomm->
comm() );
199 hypre_FinalizeTiming( time_index );
202 HYPRE_ParCSRPCGGetNumIterations( pcg_solver, &num_iterations );
203 HYPRE_ParCSRPCGGetFinalRelativeResidualNorm( pcg_solver, &final_res_norm );
204 MPI_Comm_rank( pcomm->
comm(), &myid );
208 cout <<
"PCG Iterations = " << num_iterations << endl
209 <<
"Final PCG Relative Residual Norm = " << final_res_norm << endl;
216 HyprePCG::~HyprePCG()
218 HYPRE_ParCSRPCGDestroy( pcg_solver );
221 HypreGMRES::HypreGMRES( HypreParMatrix& _A ) : HypreSolver( &_A, true )
227 iterative_mode =
true;
228 HYPRE_ParCSRMatrixGetComm( *A, &comm );
229 HYPRE_ParCSRGMRESCreate( comm, &gmres_solver );
230 HYPRE_ParCSRGMRESSetKDim( gmres_solver, k_dim );
231 HYPRE_ParCSRGMRESSetMaxIter( gmres_solver, max_iter );
232 HYPRE_ParCSRGMRESSetTol( gmres_solver, tol );
235 void HypreGMRES::SetTol(
double atol,
double rtol )
237 HYPRE_GMRESSetAbsoluteTol( gmres_solver, atol );
238 HYPRE_GMRESSetTol( gmres_solver, rtol );
241 void HypreGMRES::SetMaxIter(
int max_iter )
243 HYPRE_GMRESSetMaxIter( gmres_solver, max_iter );
246 void HypreGMRES::SetKDim(
int k_dim )
248 HYPRE_GMRESSetKDim( gmres_solver, k_dim );
251 void HypreGMRES::SetLogging(
int logging )
253 HYPRE_GMRESSetLogging( gmres_solver, logging );
256 void HypreGMRES::Verbosity(
int print_lvl )
258 HYPRE_GMRESSetPrintLevel( gmres_solver, print_lvl );
261 void HypreGMRES::SetPreconditioner( HypreSolver& precond )
263 HYPRE_ParCSRGMRESSetPrecond( gmres_solver, precond.SolveFcn(), precond.SetupFcn(), precond );
266 HYPRE_Int HypreGMRES::Solve(
const HypreParVector& b, HypreParVector& x )
const
270 HYPRE_Int time_index = 0;
271 HYPRE_Int num_iterations;
272 double final_res_norm;
274 HYPRE_Int print_level;
275 HYPRE_GMRESGetPrintLevel( gmres_solver, &print_level );
276 HYPRE_ParCSRMatrixGetComm( *A, &comm );
280 if( print_level > 0 )
283 time_index = hypre_InitializeTiming(
"GMRES Setup" );
284 hypre_BeginTiming( time_index );
288 err = HYPRE_ParCSRGMRESSetup( gmres_solver, *A, b, x );
293 cout <<
"PCG Setup failed with error = " << err << endl;
297 if( print_level > 0 )
300 hypre_EndTiming( time_index );
301 hypre_PrintTiming(
"Setup phase times", comm );
302 hypre_FinalizeTiming( time_index );
308 if( print_level > 0 )
311 time_index = hypre_InitializeTiming(
"GMRES Solve" );
312 hypre_BeginTiming( time_index );
316 if( !iterative_mode )
321 err = HYPRE_ParCSRGMRESSolve( gmres_solver, *A, b, x );
323 if( print_level > 0 )
326 hypre_EndTiming( time_index );
327 hypre_PrintTiming(
"Solve phase times", comm );
328 hypre_FinalizeTiming( time_index );
331 HYPRE_ParCSRGMRESGetNumIterations( gmres_solver, &num_iterations );
332 HYPRE_ParCSRGMRESGetFinalRelativeResidualNorm( gmres_solver, &final_res_norm );
333 MPI_Comm_rank( comm, &myid );
337 cout <<
"GMRES Iterations = " << num_iterations << endl
338 <<
"Final GMRES Relative Residual Norm = " << final_res_norm << endl;
345 HypreGMRES::~HypreGMRES()
347 HYPRE_ParCSRGMRESDestroy( gmres_solver );
350 HypreParaSails::HypreParaSails( HypreParMatrix& A ) : HypreSolver( &A )
353 int sai_max_levels = 1;
354 double sai_threshold = 0.1;
355 double sai_filter = 0.1;
357 double sai_loadbal = 0.0;
360 HYPRE_ParCSRMatrixGetComm( A, &comm );
361 HYPRE_ParaSailsCreate( comm, &sai_precond );
362 HYPRE_ParaSailsSetParams( sai_precond, sai_threshold, sai_max_levels );
363 HYPRE_ParaSailsSetFilter( sai_precond, sai_filter );
364 HYPRE_ParaSailsSetSym( sai_precond, sai_sym );
365 HYPRE_ParaSailsSetLoadbal( sai_precond, sai_loadbal );
366 HYPRE_ParaSailsSetReuse( sai_precond, sai_reuse );
367 HYPRE_ParaSailsSetLogging( sai_precond, sai_logging );
370 void HypreParaSails::SetSymmetry(
int sym )
372 HYPRE_ParaSailsSetSym( sai_precond, sym );
375 HypreParaSails::~HypreParaSails()
377 HYPRE_ParaSailsDestroy( sai_precond );
380 HypreBoomerAMG::HypreBoomerAMG()
382 HYPRE_BoomerAMGCreate( &amg_precond );
386 HypreBoomerAMG::HypreBoomerAMG( HypreParMatrix& A ) : HypreSolver( &A )
388 HYPRE_BoomerAMGCreate( &amg_precond );
392 void HypreBoomerAMG::SetDefaultOptions()
395 int coarsen_type = 10;
403 int relax_sweeps = 1;
407 HYPRE_BoomerAMGSetCoarsenType( amg_precond, coarsen_type );
408 HYPRE_BoomerAMGSetAggNumLevels( amg_precond, agg_levels );
409 HYPRE_BoomerAMGSetRelaxType( amg_precond, relax_type );
410 HYPRE_BoomerAMGSetNumSweeps( amg_precond, relax_sweeps );
411 HYPRE_BoomerAMGSetStrongThreshold( amg_precond, theta );
412 HYPRE_BoomerAMGSetInterpType( amg_precond, interp_type );
413 HYPRE_BoomerAMGSetPMaxElmts( amg_precond, Pmax );
414 HYPRE_BoomerAMGSetPrintLevel( amg_precond, print_level );
415 HYPRE_BoomerAMGSetMaxLevels( amg_precond, max_levels );
417 HYPRE_BoomerAMGSetMaxIter( amg_precond, 1 );
418 HYPRE_BoomerAMGSetTol( amg_precond, 0.0 );
421 void HypreBoomerAMG::ResetAMGPrecond()
423 HYPRE_Int coarsen_type;
424 HYPRE_Int agg_levels;
425 HYPRE_Int relax_type;
426 HYPRE_Int relax_sweeps;
428 HYPRE_Int interp_type;
430 HYPRE_Int print_level;
432 hypre_ParAMGData* amg_data = (hypre_ParAMGData*)amg_precond;
434 HYPRE_BoomerAMGGetCoarsenType( amg_precond, &coarsen_type );
435 agg_levels = hypre_ParAMGDataAggNumLevels( amg_data );
436 relax_type = hypre_ParAMGDataUserRelaxType( amg_data );
437 relax_sweeps = hypre_ParAMGDataUserNumSweeps( amg_data );
438 HYPRE_BoomerAMGGetStrongThreshold( amg_precond, &theta );
439 hypre_BoomerAMGGetInterpType( amg_precond, &interp_type );
440 HYPRE_BoomerAMGGetPMaxElmts( amg_precond, &Pmax );
441 HYPRE_BoomerAMGGetPrintLevel( amg_precond, &print_level );
442 HYPRE_BoomerAMGGetNumFunctions( amg_precond, &
dim );
443 HYPRE_BoomerAMGDestroy( amg_precond );
444 HYPRE_BoomerAMGCreate( &amg_precond );
445 HYPRE_BoomerAMGSetCoarsenType( amg_precond, coarsen_type );
446 HYPRE_BoomerAMGSetAggNumLevels( amg_precond, agg_levels );
447 HYPRE_BoomerAMGSetRelaxType( amg_precond, relax_type );
448 HYPRE_BoomerAMGSetNumSweeps( amg_precond, relax_sweeps );
449 HYPRE_BoomerAMGSetMaxLevels( amg_precond, 25 );
450 HYPRE_BoomerAMGSetTol( amg_precond, 0.0 );
451 HYPRE_BoomerAMGSetMaxIter( amg_precond, 1 );
452 HYPRE_BoomerAMGSetStrongThreshold( amg_precond, theta );
453 HYPRE_BoomerAMGSetInterpType( amg_precond, interp_type );
454 HYPRE_BoomerAMGSetPMaxElmts( amg_precond, Pmax );
455 HYPRE_BoomerAMGSetPrintLevel( amg_precond, print_level );
456 HYPRE_BoomerAMGSetNumFunctions( amg_precond,
dim );
459 void HypreBoomerAMG::SetOperator(
const HypreParMatrix& op )
467 A =
const_cast< HypreParMatrix*
>( &op );
474 void HypreBoomerAMG::SetSystemsOptions(
int dim )
476 HYPRE_BoomerAMGSetNumFunctions( amg_precond,
dim );
478 HYPRE_BoomerAMGSetAggNumLevels( amg_precond, 0 );
479 HYPRE_BoomerAMGSetStrongThreshold( amg_precond,
dim * 0.25 );
482 HypreBoomerAMG::~HypreBoomerAMG()
484 HYPRE_BoomerAMGDestroy( amg_precond );