28 #include <oomph-lib-config.h>
38 #ifdef OOMPH_HAS_HYPRE
45 namespace Biharmonic_schur_complement_Hypre_defaults
86 oomph_info <<
"Re-assigned number of v cycles: "
93 oomph_info <<
"Current number of amg smoother iterations: "
98 oomph_info <<
"Re-assigned number of amg smoother iterations: "
116 std::ostringstream error_message;
117 error_message <<
"The bulk element mesh has not been passed to "
118 "bulk_element_mesh_pt()";
120 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
146 std::ostringstream error_message;
147 error_message <<
"Preconditioner_type must be equal to 0 (BBD exact), 1 "
148 "(inexact BBD with LU),"
149 <<
" 2 (inexact BBD with AMG) or 3 (exact BD).";
151 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
157 bool retain_all_blocks =
false;
163 retain_all_blocks =
false;
195 retain_all_blocks =
true;
206 OOMPH_CURRENT_FUNCTION,
207 OOMPH_EXCEPTION_LOCATION);
287 if (n_block_types != 3)
289 std::ostringstream error_message;
291 <<
"This preconditioner requires 3 block types.\n"
292 <<
"It is sub preconditioner for the BiharmonicPreconditioner.\n";
294 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
304 const bool want_block =
true;
305 for (
unsigned b_i = 0; b_i < n_block_types; b_i++)
307 for (
unsigned b_j = 0; b_j < n_block_types; b_j++)
309 required_blocks[b_i][b_j].select_block(b_i, b_j, want_block);
316 required_blocks[1][2].do_not_want_block();
317 required_blocks[2][1].do_not_want_block();
369 if (n_block_types != 3)
371 std::ostringstream error_message;
373 <<
"This preconditioner requires 3 block types.\n"
374 <<
"It is sub preconditioner for the BiharmonicPreconditioner.\n";
376 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
382 required_blocks(0, 0) =
true;
383 required_blocks(0, 1) =
true;
384 required_blocks(1, 0) =
true;
385 required_blocks(1, 1) =
true;
386 required_blocks(0, 2) =
true;
387 required_blocks(2, 0) =
true;
388 required_blocks(2, 2) =
true;
417 #ifdef OOMPH_HAS_HYPRE
423 std::ostringstream error_message;
424 error_message <<
"Request AMG solver but oomph-lib does not have HYPRE";
426 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
449 int* J_01_row_start = 0;
450 int* J_01_column_index = 0;
451 double* J_01_value = 0;
452 int* J_10_row_start = 0;
453 int* J_10_column_index = 0;
465 int* J_02_row_start = 0;
466 int* J_02_column_index = 0;
467 double* J_02_value = 0;
468 int* J_20_row_start = 0;
469 int* J_20_column_index = 0;
481 double* J_11_lumped_and_inverted = 0;
482 J_11_lumped_and_inverted =
486 double* J_22_lumped_and_inverted = 0;
487 J_22_lumped_and_inverted =
499 unsigned n_element_x =
503 ->bulk_element_mesh_pt())
504 ->nelement_in_dim(0);
507 unsigned S_00_nnz = 0;
510 for (
unsigned i = 0;
i < J_00_nrow;
i++)
513 S_00_row_start[
i] = S_00_nnz;
535 band_position[0].first =
536 std::max(0,
static_cast<int>(
i - n_element_x * 2 - 5));
537 band_position[0].second =
539 std::min(
static_cast<int>(J_00_nrow - 1),
540 static_cast<int>(
i - n_element_x * 2 + 5)));
541 band_position[1].first =
542 std::max(band_position[0].second + 1,
543 std::max(0,
static_cast<int>(
i - n_element_x - 3)));
544 band_position[1].second =
546 std::min(
static_cast<int>(J_00_nrow - 1),
547 static_cast<int>(
i - n_element_x + 3)));
548 band_position[2].first = std::max(band_position[1].second + 1,
549 std::max(0,
static_cast<int>(
i - 3)));
550 band_position[2].second = std::max(
551 0, std::min(
static_cast<int>(J_00_nrow - 1),
static_cast<int>(
i + 3)));
552 band_position[3].first =
553 std::max(band_position[2].second + 1,
554 std::max(0,
static_cast<int>(
i + n_element_x - 3)));
555 band_position[3].second =
557 std::min(
static_cast<int>(J_00_nrow - 1),
558 static_cast<int>(
i + n_element_x + 3)));
559 band_position[4].first =
560 std::max(band_position[3].second + 1,
561 std::max(0,
static_cast<int>(
i + n_element_x * 2 - 5)));
562 band_position[4].second =
564 std::min(
static_cast<int>(J_00_nrow - 1),
565 static_cast<int>(
i + n_element_x * 2 + 5)));
571 for (
unsigned b = 0; b < n_band; b++)
574 for (
unsigned j =
static_cast<unsigned>(band_position[b].first);
575 j <= static_cast<unsigned>(band_position[b].second);
584 for (
int k = J_01_row_start[
i]; k < J_01_row_start[
i + 1]; k++)
586 if (J_10_column_index[J_10_row_start[J_01_column_index[k]]] <=
587 static_cast<int>(j) &&
588 static_cast<int>(j) <=
589 J_10_column_index[J_10_row_start[J_01_column_index[k] + 1] -
592 temp_value -= J_01_value[k] *
594 J_01_column_index[k], j) *
595 J_11_lumped_and_inverted[J_01_column_index[k]];
602 for (
int k = J_02_row_start[
i]; k < J_02_row_start[
i + 1]; k++)
604 if (J_20_column_index[J_20_row_start[J_02_column_index[k]]] <=
605 static_cast<int>(j) &&
606 static_cast<int>(j) <=
607 J_20_column_index[J_20_row_start[J_02_column_index[k] + 1] -
610 temp_value -= J_02_value[k] *
612 J_02_column_index[k], j) *
613 J_22_lumped_and_inverted[J_02_column_index[k]];
618 if (temp_value != 0.0)
621 S_00_value.push_back(temp_value);
622 S_00_column_index.push_back(j);
629 S_00_row_start[J_00_nrow] = S_00_nnz;
640 for (
unsigned i = 0;
i < J_01_nnz;
i++)
642 J_01_value[
i] *= J_11_lumped_and_inverted[J_01_column_index[
i]];
647 for (
unsigned i = 0;
i < J_02_nnz;
i++)
649 J_02_value[
i] *= J_22_lumped_and_inverted[J_02_column_index[
i]];
Biharmonic Preconditioner - for two dimensional problems.
Preconditioner * Hijacked_sub_block_preconditioner_pt
Preconditioner the diagonal block associated with hijacked elements.
Preconditioner * Sub_preconditioner_2_pt
Inexact Preconditioner Pointer.
void clean_up_memory()
Clean up memory (empty). Generic interface function.
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to r.
void setup()
Setup the preconditioner.
unsigned Preconditioner_type
preconditioner type
Mesh * Bulk_element_mesh_pt
the bulk element mesh pt
Preconditioner * Sub_preconditioner_1_pt
Exact Preconditioner Pointer.
void return_block_vector(const unsigned &n, const DoubleVector &b, DoubleVector &v) const
Takes the n-th block ordered vector, b, and copies its entries to the appropriate entries in the natu...
CRDoubleMatrix get_concatenated_block(const VectorMatrix< BlockSelector > &selected_block)
Returns a concatenation of the block matrices specified by the argument selected_block....
void get_blocks(DenseMatrix< bool > &required_blocks, DenseMatrix< CRDoubleMatrix * > &block_matrix_pt) const
Get all the block matrices required by the block preconditioner. Takes a pointer to a matrix of bools...
void get_block(const unsigned &i, const unsigned &j, CRDoubleMatrix &output_matrix, const bool &ignore_replacement_block=false) const
Put block (i,j) into output_matrix. This block accounts for any coarsening of dof types and any repla...
const LinearAlgebraDistribution * block_distribution_pt(const unsigned &b) const
Access function to the block distributions (const version).
void get_block_vector(const unsigned &n, const DoubleVector &v, DoubleVector &b) const
Takes the naturally ordered vector, v and returns the n-th block vector, b. Here n is the block numbe...
unsigned nblock_types() const
Return the number of block types.
void return_block_ordered_preconditioner_vector(const DoubleVector &w, DoubleVector &v) const
Takes the block ordered vector, w, and reorders it in natural order. Reordered vector is returned in ...
CRDoubleMatrix * matrix_pt() const
Access function to matrix_pt. If this is the master then cast the matrix pointer to MATRIX*,...
BlockPreconditioner< CRDoubleMatrix > * master_block_preconditioner_pt() const
Access function to the master block preconditioner pt.
void get_block_vectors(const Vector< unsigned > &block_vec_number, const DoubleVector &v, Vector< DoubleVector > &s) const
Takes the naturally ordered vector and rearranges it into a vector of sub vectors corresponding to th...
virtual void block_setup()
Determine the size of the matrix blocks and setup the lookup schemes relating the global degrees of f...
void set_mesh(const unsigned &i, const Mesh *const mesh_pt, const bool &allow_multiple_element_type_in_mesh=false)
Set the i-th mesh for this block preconditioner. Note: The method set_nmesh(...) must be called befor...
void get_block_ordered_preconditioner_vector(const DoubleVector &v, DoubleVector &w)
Given the naturally ordered vector, v, return the vector rearranged in block order in w....
A class for compressed row matrices. This is a distributable object.
A vector in the mathematical sense, initially developed for linear algebra type applications....
void initialise(const double &v)
initialise the whole vector with value v
void clear()
wipes the DoubleVector
Sub Biharmonic Preconditioner - an exact preconditioner for the 3x3 top left hand corner sub block ma...
void clean_up_memory()
delete the subsidiary preconditioner pointer
Preconditioner * Sub_preconditioner_pt
bool Retain_all_blocks
Boolean indicating that all blocks are to be retained (defaults to false)
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to r.
void setup()
Setup the preconditioner.
A two dimensional Hermite bicubic element quadrilateral mesh for a topologically rectangular domain....
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
unsigned & amg_smoother_iterations()
Access function to AMG_smoother_iterations.
unsigned & amg_simple_smoother()
Access function to AMG_simple_smoother flag.
double & amg_strength()
Access function to AMG_strength.
unsigned & amg_iterations()
Return function for Max_iter.
unsigned & hypre_method()
Access function to Hypre_method flag – specified via enumeration.
unsigned & amg_coarsening()
Access function to AMG_coarsening flag.
SubBiharmonic Preconditioner - an inexact preconditioner for the 3x3 top left hand corner sub block m...
DenseMatrix< CRDoubleMatrix * > Matrix_of_block_pointers
void compute_inexact_schur_complement()
Computes the inexact schur complement of the block J_00 using lumping as an approximate inverse of bl...
Preconditioner * S_00_preconditioner_pt
Pointer to the S00 Schur Complement preconditioner.
unsigned Use_amg
booean indicating whether (Hypre BoomerAMG) AMG should be used to solve the S00 subsidiary linear sys...
void clean_up_memory()
clean the memory
MatrixBasedLumpedPreconditioner< CRDoubleMatrix > * Lumped_J_22_preconditioner_pt
Preconditioner for storing the lumped J_22 matrix.
void setup()
Setup the preconditioner.
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to r.
MatrixBasedLumpedPreconditioner< CRDoubleMatrix > * Lumped_J_11_preconditioner_pt
Preconditioner for storing the lumped J_11 matrix.
Matrix-based diagonal preconditioner.
Matrix-based lumped preconditioner.
An OomphLibError object which should be thrown when an run-time error is encountered....
void setup(DoubleMatrixBase *matrix_pt)
Setup the preconditioner: store the matrix pointer and the communicator pointer then call preconditio...
virtual void preconditioner_solve(const DoubleVector &r, DoubleVector &z)=0
Apply the preconditioner. Pure virtual generic interface function. This method should apply the preco...
An interface to allow SuperLU to be used as an (exact) Preconditioner.
VectorMatrix is a generalised, STL-map-based, matrix based on a Vector of Vectors.
unsigned N_cycle
number of V cycles: 2
double AMG_jacobi_damping
jacobi damping – hierher not used 0.1
unsigned AMG_smoother
smoother type - Gauss Seidel: 1
void set_defaults(HyprePreconditioner *hypre_prec_pt)
set the defaults
unsigned AMG_coarsening
amg coarsening strategy: classical Ruge Stueben: 1
double AMG_strength
amg strength parameter: 0.25 – optimal for 2d
unsigned AMG_smoother_iterations
amg smoother iterations
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...