oomph::HypreHelpers Namespace Reference

Helper functions for use with the Hypre library. More...

Functions

int check_HYPRE_error_flag (std::ostringstream &message)
 
void create_HYPRE_Vector (const DoubleVector &oomph_vec, const LinearAlgebraDistribution *dist_pt, HYPRE_IJVector &hypre_ij_vector, HYPRE_ParVector &hypre_par_vector)
 
void create_HYPRE_Vector (const LinearAlgebraDistribution *dist_pt, HYPRE_IJVector &hypre_ij_vector, HYPRE_ParVector &hypre_par_vector)
 
void create_HYPRE_Matrix (CRDoubleMatrix *oomph_matrix, HYPRE_IJMatrix &hypre_ij_matrix, HYPRE_ParCSRMatrix &hypre_par_matrix, LinearAlgebraDistribution *dist_pt)
 
void euclid_settings_helper (const bool &use_block_jacobi, const bool &use_row_scaling, const bool &use_ilut, const int &level, const double &drop_tol, const int &print_level, HYPRE_Solver &euclid_object)
 

Variables

double AMG_strength = 0.25
 
unsigned AMG_coarsening = 6
 
double AMG_truncation = 0.0
 AMG interpolation truncation factor. More...
 

Detailed Description

Helper functions for use with the Hypre library.

///////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////

Function Documentation

◆ check_HYPRE_error_flag()

int oomph::HypreHelpers::check_HYPRE_error_flag ( std::ostringstream &  message)

Helper function to check the Hypre error flag, return the message associated with any error, and reset the global error flag to zero. This function also returns the error value.

Helper function to check the Hypre error flag, return the message associated with any error, and reset the error flag to zero.

148  {
149  // get the Hypre error flag
150  int err = HYPRE_GetError();
151 
152  // Tell us all about it...
153  if (err)
154  {
155  oomph_info << "Hypre error flag=" << err << std::endl;
156  char* error_message = new char[128];
157  HYPRE_DescribeError(err, error_message);
158  message << "WARNING: " << std::endl
159  << "HYPRE error message: " << error_message << std::endl;
160  delete[] error_message;
161  }
162 
163  // reset Hypre's global error flag
165 
166  return err;
167  }
int hypre__global_error
OomphInfo oomph_info
Definition: oomph_definitions.cc:319

References hypre__global_error, and oomph::oomph_info.

Referenced by oomph::HypreInterface::hypre_clean_up_memory(), oomph::HypreInterface::hypre_matrix_setup(), oomph::HypreInterface::hypre_solve(), and oomph::HypreInterface::hypre_solver_setup().

◆ create_HYPRE_Matrix()

void oomph::HypreHelpers::create_HYPRE_Matrix ( CRDoubleMatrix oomph_matrix,
HYPRE_IJMatrix &  hypre_ij_matrix,
HYPRE_ParCSRMatrix &  hypre_par_matrix,
LinearAlgebraDistribution dist_pt 
)

Helper function to create a serial HYPRE_IJMatrix and HYPRE_ParCSRMatrix from a CRDoubleMatrix NOTE: dist_pt is rebuilt to match the distribution of the hypre solver which is not necassarily the same as the oomph lib matrix

Helper function to create a serial HYPRE_IJMatrix and HYPRE_ParCSRMatrix from a CRDoubleMatrix

274  {
275 #ifdef PARANOID
276  // check that the matrix is built
277  if (!oomph_matrix->built())
278  {
279  std::ostringstream error_message;
280  error_message << "The matrix has not been built";
281  throw OomphLibError(error_message.str(),
284  }
285  // check the matrix is square
286  if (oomph_matrix->nrow() != oomph_matrix->ncol())
287  {
288  std::ostringstream error_message;
289  error_message << "create_HYPRE_Matrix require a square matrix. "
290  << "Matrix is " << oomph_matrix->nrow() << " by "
291  << oomph_matrix->ncol() << std::endl;
292  throw OomphLibError(error_message.str(),
295  }
296 #endif
297 
298 #ifdef OOMPH_HAS_MPI
299  // Trap the case when we have compiled with MPI,
300  // but are running in serial
301  if (!MPI_Helpers::mpi_has_been_initialised())
302  {
303  std::ostringstream error_stream;
304  error_stream
305  << "Oomph-lib has been compiled with MPI support and "
306  << "you are using HYPRE.\n"
307  << "For this combination of flags, MPI must be initialised.\n"
308  << "Call MPI_Helpers::init() in the "
309  << "main() function of your driver code\n";
310  throw OomphLibError(
311  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
312  }
313 #endif
314 
315  // find number of rows/columns
316  const unsigned nrow = int(oomph_matrix->nrow());
317 
318  // get pointers to the matrix
319 
320  // column indices of matrix
321  const int* matrix_cols = oomph_matrix->column_index();
322 
323  // entries of matrix
324  const double* matrix_vals = oomph_matrix->value();
325 
326  // row starts
327  const int* matrix_row_start = oomph_matrix->row_start();
328 
329  // build the distribution
330  if (oomph_matrix->distribution_pt()->distributed())
331  {
332  dist_pt->build(oomph_matrix->distribution_pt());
333  }
334  else
335  {
336  bool distributed = true;
337  if (oomph_matrix->distribution_pt()->communicator_pt()->nproc() == 1)
338  {
339  distributed = false;
340  }
341  dist_pt->build(oomph_matrix->distribution_pt()->communicator_pt(),
342  nrow,
343  distributed);
344  }
345 
346  // initialize hypre matrix
347  unsigned lower = dist_pt->first_row();
348  unsigned upper = lower + dist_pt->nrow_local() - 1;
349 
350 #ifdef OOMPH_HAS_MPI
351  HYPRE_IJMatrixCreate(dist_pt->communicator_pt()->mpi_comm(),
352  lower,
353  upper,
354  lower,
355  upper,
356  &hypre_ij_matrix);
357 #else
358  HYPRE_IJMatrixCreate(
359  MPI_COMM_WORLD, lower, upper, lower, upper, &hypre_ij_matrix);
360 #endif
361  HYPRE_IJMatrixSetObjectType(hypre_ij_matrix, HYPRE_PARCSR);
362  HYPRE_IJMatrixInitialize(hypre_ij_matrix);
363 
364  // set up a row map
365  // and first row / nrow_local
366  const unsigned hypre_nrow_local = dist_pt->nrow_local();
367  const unsigned hypre_first_row = dist_pt->first_row();
368  int* ncols_per_row = new int[hypre_nrow_local];
369  int* row_map = new int[hypre_nrow_local];
370  for (unsigned i = 0; i < hypre_nrow_local; i++)
371  {
372  unsigned j = i;
373  if (!oomph_matrix->distributed() && dist_pt->distributed())
374  {
375  j += hypre_first_row;
376  }
377  ncols_per_row[i] = matrix_row_start[j + 1] - matrix_row_start[j];
378  row_map[i] = hypre_first_row + i;
379  }
380 
381  // put values in HYPRE matrix
382  int local_start = 0;
383  if (!oomph_matrix->distributed() && dist_pt->distributed())
384  {
385  local_start += matrix_row_start[hypre_first_row];
386  }
387 
388 
389  HYPRE_IJMatrixSetValues(hypre_ij_matrix,
390  hypre_nrow_local,
391  ncols_per_row,
392  row_map,
393  matrix_cols + local_start,
394  matrix_vals + local_start);
395 
396  // assemble matrix
397  HYPRE_IJMatrixAssemble(hypre_ij_matrix); // hierher leak?
398  HYPRE_IJMatrixGetObject(hypre_ij_matrix, (void**)&hypre_par_matrix);
399 
400  // tidy up memory
401  delete[] ncols_per_row;
402  delete[] row_map;
403  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
return int(ret)+1
std::string lower(std::string s)
returns the input string after converting upper-case characters to lower case
Definition: StringHelpers.cc:11
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References oomph::LinearAlgebraDistribution::build(), oomph::CRDoubleMatrix::built(), oomph::CRDoubleMatrix::column_index(), oomph::LinearAlgebraDistribution::communicator_pt(), oomph::LinearAlgebraDistribution::distributed(), oomph::DistributableLinearAlgebraObject::distributed(), oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::LinearAlgebraDistribution::first_row(), i, int(), j, helpers::lower(), oomph::MPI_Helpers::mpi_has_been_initialised(), oomph::CRDoubleMatrix::ncol(), oomph::OomphCommunicator::nproc(), oomph::CRDoubleMatrix::nrow(), oomph::LinearAlgebraDistribution::nrow_local(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::CRDoubleMatrix::row_start(), and oomph::CRDoubleMatrix::value().

Referenced by oomph::HypreInterface::hypre_matrix_setup().

◆ create_HYPRE_Vector() [1/2]

void oomph::HypreHelpers::create_HYPRE_Vector ( const DoubleVector oomph_vec,
const LinearAlgebraDistribution dist_pt,
HYPRE_IJVector &  hypre_ij_vector,
HYPRE_ParVector &  hypre_par_vector 
)

Helper function to create a HYPRE_IJVector and HYPRE_ParVector.

  • If no MPI then serial vectors are created
  • If MPI and serial input vector then distributed hypre vectors are created
  • If MPI and distributed input vector the distributed output vectors are created.
182  {
183  // the lower and upper row of the vector on this processor
184  unsigned lower = dist_pt->first_row();
185  unsigned upper = dist_pt->first_row() + dist_pt->nrow_local() - 1;
186 
187  // number of local rows
188  unsigned nrow_local = dist_pt->nrow_local();
189 
190  // initialize Hypre vector
191 #ifdef OOMPH_HAS_MPI
192  HYPRE_IJVectorCreate(
193  oomph_vec.distribution_pt()->communicator_pt()->mpi_comm(),
194  lower,
195  upper,
196  &hypre_ij_vector);
197 #else
198  HYPRE_IJVectorCreate(MPI_COMM_WORLD, lower, upper, &hypre_ij_vector);
199 #endif
200  HYPRE_IJVectorSetObjectType(hypre_ij_vector, HYPRE_PARCSR);
201  HYPRE_IJVectorInitialize(hypre_ij_vector);
202 
203  // set up array containing indices
204  int* indices = new int[nrow_local];
205  double* values = new double[nrow_local];
206  const unsigned hypre_first_row = dist_pt->first_row();
207  unsigned j = 0;
208  if (!oomph_vec.distributed() && dist_pt->distributed())
209  {
210  j = hypre_first_row;
211  }
212  const double* o_pt = oomph_vec.values_pt();
213  for (unsigned i = 0; i < nrow_local; i++)
214  {
215  indices[i] = hypre_first_row + i;
216  values[i] = o_pt[j + i];
217  }
218 
219  // insert values
220  HYPRE_IJVectorSetValues(hypre_ij_vector, nrow_local, indices, values);
221 
222  // assemble vectors
223  HYPRE_IJVectorAssemble(hypre_ij_vector);
224  HYPRE_IJVectorGetObject(hypre_ij_vector, (void**)&hypre_par_vector);
225 
226  // clean up
227  delete[] indices;
228  delete[] values;
229  }

References oomph::LinearAlgebraDistribution::communicator_pt(), oomph::LinearAlgebraDistribution::distributed(), oomph::DistributableLinearAlgebraObject::distributed(), oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::LinearAlgebraDistribution::first_row(), i, j, helpers::lower(), oomph::LinearAlgebraDistribution::nrow_local(), and oomph::DoubleVector::values_pt().

Referenced by oomph::HypreInterface::hypre_solve(), and oomph::HypreInterface::hypre_solver_setup().

◆ create_HYPRE_Vector() [2/2]

void oomph::HypreHelpers::create_HYPRE_Vector ( const LinearAlgebraDistribution dist_pt,
HYPRE_IJVector &  hypre_ij_vector,
HYPRE_ParVector &  hypre_par_vector 
)

Helper function to create a HYPRE_IJVector and HYPRE_ParVector.

  • If no MPI then serial vectors are created
  • If MPI and serial input vector then distributed hypre vectors are created
  • If MPI and distributed input vector the distributed output vectors are created.

Helper function to create an empty HYPRE_IJVector and HYPRE_ParVector.

  • If no MPI then serial vectors are created
  • If MPI and serial distribution then distributed hypre vectors are created
  • If MPI and distributed input distribution the distributed output vectors are created.
243  {
244  // the lower and upper row of the vector on this processor
245  unsigned lower = dist_pt->first_row();
246  unsigned upper = dist_pt->first_row() + dist_pt->nrow_local() - 1;
247 
248  // initialize Hypre vector
249 #ifdef OOMPH_HAS_MPI
250  HYPRE_IJVectorCreate(
251  dist_pt->communicator_pt()->mpi_comm(), lower, upper, &hypre_ij_vector);
252 #else
253  HYPRE_IJVectorCreate(MPI_COMM_WORLD, lower, upper, &hypre_ij_vector);
254 #endif
255  HYPRE_IJVectorSetObjectType(hypre_ij_vector, HYPRE_PARCSR);
256  HYPRE_IJVectorInitialize(hypre_ij_vector);
257 
258  // assemble vectors
259  HYPRE_IJVectorAssemble(hypre_ij_vector);
260  HYPRE_IJVectorGetObject(hypre_ij_vector, (void**)&hypre_par_vector);
261  }

References oomph::LinearAlgebraDistribution::communicator_pt(), oomph::LinearAlgebraDistribution::first_row(), helpers::lower(), and oomph::LinearAlgebraDistribution::nrow_local().

◆ euclid_settings_helper()

void oomph::HypreHelpers::euclid_settings_helper ( const bool use_block_jacobi,
const bool use_row_scaling,
const bool use_ilut,
const int level,
const double drop_tol,
const int print_level,
HYPRE_Solver &  euclid_object 
)

Helper function to set Euclid options using a command line like array.

416  {
417  // Easier to use C-arrays rather than std::strings because Euclid takes
418  // char** as argument and because C++ doesn't provide decent number to
419  // std::string conversion functions.
420 
421  int n_args = 0;
422  const char* args[22];
423 
424  // first argument is empty string
425  args[n_args++] = "";
426 
427  // switch on/off Block Jacobi ILU
428  args[n_args++] = "-bj";
429  if (use_block_jacobi)
430  {
431  args[n_args++] = "1";
432  }
433  else
434  {
435  args[n_args++] = "0";
436  }
437 
438  // switch on/off row scaling
439  args[n_args++] = "-rowScale";
440  if (use_row_scaling)
441  {
442  args[n_args++] = "1";
443  }
444  else
445  {
446  args[n_args++] = "0";
447  }
448 
449  // set level for ILU(k)
450  args[n_args++] = "-level";
451  char level_value[10];
452  sprintf(level_value, "%d", level);
453  args[n_args++] = level_value;
454 
455  // // set drop tol for ILU(k) factorization
456  // args[n_args++] = "-sparseA";
457  // char droptol[20];
458  // sprintf(droptol,"%f",drop_tol);
459  // args[n_args++] = droptol;
460 
461  // // set ILUT factorization if required
462  // if (use_ilut)
463  // {
464  // args[n_args++] = "-ilut";
465  // args[n_args++] = droptol;
466  // }
467 
468  // set printing of Euclid data
469  if (print_level == 0)
470  {
471  args[n_args++] = "-eu_stats";
472  args[n_args++] = "0";
473  args[n_args++] = "-eu_mem";
474  args[n_args++] = "0";
475  }
476  if (print_level == 1)
477  {
478  args[n_args++] = "-eu_stats";
479  args[n_args++] = "1";
480  args[n_args++] = "-eu_mem";
481  args[n_args++] = "0";
482  }
483  if (print_level == 2)
484  {
485  args[n_args++] = "-eu_stats";
486  args[n_args++] = "1";
487  args[n_args++] = "-eu_mem";
488  args[n_args++] = "1";
489  }
490 
491  // set next entry in array to null
492  args[n_args] = 0;
493 
494  // Send the parameters
495  HYPRE_EuclidSetParams(euclid_object, n_args, const_cast<char**>(args));
496  }
args
Definition: compute_granudrum_aor.py:143

References compute_granudrum_aor::args.

Referenced by oomph::HypreInterface::hypre_solver_setup().

Variable Documentation

◆ AMG_coarsening

unsigned oomph::HypreHelpers::AMG_coarsening = 6

Default AMG coarsening strategy. Coarsening types include: 0 = CLJP (parallel coarsening using independent sets) 1 = classical RS with no boundary treatment (not recommended in parallel) 3 = modified RS with 3rd pass to add C points on the boundaries 6 = Falgout (uses 1 then CLJP using interior coarse points as first independent set) 8 = PMIS (parallel coarsening using independent sets - lower complexities than 0, maybe also slower convergence) 10= HMIS (one pass RS on each processor then PMIS on interior coarse points as first independent set) 11= One pass RS on each processor (not recommended)

Referenced by oomph::HypreInterface::HypreInterface().

◆ AMG_strength

double oomph::HypreHelpers::AMG_strength = 0.25

Default for AMG strength (0.25 recommended for 2D problems; larger (0.5-0.75, say) for 3D

Referenced by oomph::HypreInterface::HypreInterface().

◆ AMG_truncation

double oomph::HypreHelpers::AMG_truncation = 0.0

AMG interpolation truncation factor.

Referenced by oomph::HypreInterface::HypreInterface().