oomph::GMRESBlockPreconditioner Class Reference

#include <general_purpose_space_time_subsidiary_block_preconditioner.h>

+ Inheritance diagram for oomph::GMRESBlockPreconditioner:

Public Member Functions

 GMRESBlockPreconditioner ()
 Constructor (empty) More...
 
virtual ~GMRESBlockPreconditioner ()
 Destructor. More...
 
virtual void clean_up_memory ()
 Clean up the memory (empty for now...) More...
 
 GMRESBlockPreconditioner (const GMRESBlockPreconditioner &)=delete
 Broken copy constructor. More...
 
void operator= (const GMRESBlockPreconditioner &)=delete
 Broken assignment operator. More...
 
void setup ()
 Setup the preconditioner. More...
 
void preconditioner_solve (const DoubleVector &r, DoubleVector &z)
 Apply preconditioner to r. More...
 
void solve (Problem *const &problem_pt, DoubleVector &result)
 
unsigned iterations () const
 Handle to the number of iterations taken. More...
 
void set_preconditioner_LHS ()
 Set left preconditioning (the default) More...
 
void set_preconditioner_RHS ()
 Enable right preconditioning. More...
 
void enable_doc_memory_usage ()
 Document the memory usage. More...
 
void disable_doc_memory_usage ()
 Don't document the memory usage! More...
 
double get_memory_usage_in_bytes ()
 Get the memory statistics. More...
 
SpaceTimeNavierStokesSubsidiaryPreconditionernavier_stokes_subsidiary_preconditioner_pt () const
 
 GMRESBlockPreconditioner ()
 Constructor (empty) More...
 
virtual ~GMRESBlockPreconditioner ()
 Destructor. More...
 
virtual void clean_up_memory ()
 Clean up the memory (empty for now...) More...
 
 GMRESBlockPreconditioner (const GMRESBlockPreconditioner &)=delete
 Broken copy constructor. More...
 
void operator= (const GMRESBlockPreconditioner &)=delete
 Broken assignment operator. More...
 
void setup ()
 Setup the preconditioner. More...
 
void preconditioner_solve (const DoubleVector &r, DoubleVector &z)
 Apply preconditioner to r. More...
 
void solve (Problem *const &problem_pt, DoubleVector &result)
 
unsigned iterations () const
 Handle to the number of iterations taken. More...
 
void set_preconditioner_LHS ()
 Set left preconditioning (the default) More...
 
void set_preconditioner_RHS ()
 Enable right preconditioning. More...
 
void enable_doc_memory_statistics ()
 Document the memory usage. More...
 
void disable_doc_memory_statistics ()
 Don't document the memory usage! More...
 
double get_memory_usage_in_bytes ()
 Get the memory statistics. More...
 
SpaceTimeNavierStokesSubsidiaryPreconditionernavier_stokes_subsidiary_preconditioner_pt () const
 
void setup (DoubleMatrixBase *matrix_pt)
 
void setup (const Problem *problem_pt, DoubleMatrixBase *matrix_pt)
 
virtual void setup ()=0
 
void setup (DoubleMatrixBase *matrix_pt)
 
void setup (const Problem *problem_pt, DoubleMatrixBase *matrix_pt)
 
virtual void setup ()=0
 
- Public Member Functions inherited from oomph::IterativeLinearSolver
 IterativeLinearSolver ()
 
 IterativeLinearSolver (const IterativeLinearSolver &)=delete
 Broken copy constructor. More...
 
void operator= (const IterativeLinearSolver &)=delete
 Broken assignment operator. More...
 
virtual ~IterativeLinearSolver ()
 Destructor (empty) More...
 
Preconditioner *& preconditioner_pt ()
 Access function to preconditioner. More...
 
Preconditioner *const & preconditioner_pt () const
 Access function to preconditioner (const version) More...
 
doubletolerance ()
 Access to convergence tolerance. More...
 
unsignedmax_iter ()
 Access to max. number of iterations. More...
 
void enable_doc_convergence_history ()
 Enable documentation of the convergence history. More...
 
void disable_doc_convergence_history ()
 Disable documentation of the convergence history. More...
 
void open_convergence_history_file_stream (const std::string &file_name, const std::string &zone_title="")
 
void close_convergence_history_file_stream ()
 Close convergence history output stream. More...
 
double jacobian_setup_time () const
 
double linear_solver_solution_time () const
 return the time taken to solve the linear system More...
 
virtual double preconditioner_setup_time () const
 returns the the time taken to setup the preconditioner More...
 
void enable_setup_preconditioner_before_solve ()
 Setup the preconditioner before the solve. More...
 
void disable_setup_preconditioner_before_solve ()
 Don't set up the preconditioner before the solve. More...
 
void enable_error_after_max_iter ()
 Throw an error if we don't converge within max_iter. More...
 
void disable_error_after_max_iter ()
 Don't throw an error if we don't converge within max_iter (default). More...
 
void enable_iterative_solver_as_preconditioner ()
 
void disable_iterative_solver_as_preconditioner ()
 
- Public Member Functions inherited from oomph::LinearSolver
 LinearSolver ()
 Empty constructor, initialise the member data. More...
 
 LinearSolver (const LinearSolver &dummy)=delete
 Broken copy constructor. More...
 
void operator= (const LinearSolver &)=delete
 Broken assignment operator. More...
 
virtual ~LinearSolver ()
 Empty virtual destructor. More...
 
void enable_doc_time ()
 Enable documentation of solve times. More...
 
void disable_doc_time ()
 Disable documentation of solve times. More...
 
bool is_doc_time_enabled () const
 Is documentation of solve times enabled? More...
 
bool is_resolve_enabled () const
 Boolean flag indicating if resolves are enabled. More...
 
virtual void enable_resolve ()
 
virtual void disable_resolve ()
 
virtual void solve (DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &result)
 
virtual void solve (DoubleMatrixBase *const &matrix_pt, const Vector< double > &rhs, Vector< double > &result)
 
virtual void solve_transpose (Problem *const &problem_pt, DoubleVector &result)
 
virtual void solve_transpose (DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &result)
 
virtual void solve_transpose (DoubleMatrixBase *const &matrix_pt, const Vector< double > &rhs, Vector< double > &result)
 
virtual void resolve (const DoubleVector &rhs, DoubleVector &result)
 
virtual void resolve_transpose (const DoubleVector &rhs, DoubleVector &result)
 
virtual void enable_computation_of_gradient ()
 
void disable_computation_of_gradient ()
 
void reset_gradient ()
 
void get_gradient (DoubleVector &gradient)
 function to access the gradient, provided it has been computed More...
 
- Public Member Functions inherited from oomph::DistributableLinearAlgebraObject
 DistributableLinearAlgebraObject ()
 Default constructor - create a distribution. More...
 
 DistributableLinearAlgebraObject (const DistributableLinearAlgebraObject &matrix)=delete
 Broken copy constructor. More...
 
void operator= (const DistributableLinearAlgebraObject &)=delete
 Broken assignment operator. More...
 
virtual ~DistributableLinearAlgebraObject ()
 Destructor. More...
 
LinearAlgebraDistributiondistribution_pt () const
 access to the LinearAlgebraDistribution More...
 
unsigned nrow () const
 access function to the number of global rows. More...
 
unsigned nrow_local () const
 access function for the num of local rows on this processor. More...
 
unsigned nrow_local (const unsigned &p) const
 access function for the num of local rows on this processor. More...
 
unsigned first_row () const
 access function for the first row on this processor More...
 
unsigned first_row (const unsigned &p) const
 access function for the first row on this processor More...
 
bool distributed () const
 distribution is serial or distributed More...
 
bool distribution_built () const
 
void build_distribution (const LinearAlgebraDistribution *const dist_pt)
 
void build_distribution (const LinearAlgebraDistribution &dist)
 
- Public Member Functions inherited from oomph::BlockPreconditioner< CRDoubleMatrix >
 BlockPreconditioner ()
 Constructor. More...
 
 BlockPreconditioner (const BlockPreconditioner &)=delete
 Broken copy constructor. More...
 
virtual ~BlockPreconditioner ()
 Destructor. More...
 
void operator= (const BlockPreconditioner &)=delete
 Broken assignment operator. More...
 
CRDoubleMatrixmatrix_pt () const
 
void turn_on_recursive_debug_flag ()
 
void turn_off_recursive_debug_flag ()
 
void turn_on_debug_flag ()
 Toggles on the debug flag. More...
 
void turn_off_debug_flag ()
 Toggles off the debug flag. More...
 
void turn_into_subsidiary_block_preconditioner (BlockPreconditioner< CRDoubleMatrix > *master_block_prec_pt, const Vector< unsigned > &doftype_in_master_preconditioner_coarse)
 
void turn_into_subsidiary_block_preconditioner (BlockPreconditioner< CRDoubleMatrix > *master_block_prec_pt, const Vector< unsigned > &doftype_in_master_preconditioner_coarse, const Vector< Vector< unsigned >> &doftype_coarsen_map_coarse)
 
virtual void block_setup ()
 
void block_setup (const Vector< unsigned > &dof_to_block_map)
 
void get_block (const unsigned &i, const unsigned &j, CRDoubleMatrix &output_matrix, const bool &ignore_replacement_block=false) const
 
CRDoubleMatrix get_block (const unsigned &i, const unsigned &j, const bool &ignore_replacement_block=false) const
 
void set_master_matrix_pt (CRDoubleMatrix *in_matrix_pt)
 Set the matrix_pt in the upper-most master preconditioner. More...
 
void get_block_other_matrix (const unsigned &i, const unsigned &j, CRDoubleMatrix *in_matrix_pt, CRDoubleMatrix &output_matrix)
 
void get_blocks (DenseMatrix< bool > &required_blocks, DenseMatrix< CRDoubleMatrix * > &block_matrix_pt) const
 
void get_dof_level_block (const unsigned &i, const unsigned &j, CRDoubleMatrix &output_block, const bool &ignore_replacement_block=false) const
 
void get_dof_level_block (const unsigned &block_i, const unsigned &block_j, CRDoubleMatrix &output_block, const bool &ignore_replacement_block) const
 
CRDoubleMatrix get_concatenated_block (const VectorMatrix< BlockSelector > &selected_block)
 
void get_concatenated_block_vector (const Vector< unsigned > &block_vec_number, const DoubleVector &v, DoubleVector &b)
 
void return_concatenated_block_vector (const Vector< unsigned > &block_vec_number, const DoubleVector &b, DoubleVector &v) const
 Takes concatenated block ordered vector, b, and copies its. More...
 
void get_block_vectors (const Vector< unsigned > &block_vec_number, const DoubleVector &v, Vector< DoubleVector > &s) const
 
void get_block_vectors (const DoubleVector &v, Vector< DoubleVector > &s) const
 
void return_block_vectors (const Vector< unsigned > &block_vec_number, const Vector< DoubleVector > &s, DoubleVector &v) const
 
void return_block_vectors (const Vector< DoubleVector > &s, DoubleVector &v) const
 
void get_block_vector (const unsigned &n, const DoubleVector &v, DoubleVector &b) const
 
void return_block_vector (const unsigned &n, const DoubleVector &b, DoubleVector &v) const
 
void get_block_ordered_preconditioner_vector (const DoubleVector &v, DoubleVector &w)
 
void return_block_ordered_preconditioner_vector (const DoubleVector &w, DoubleVector &v) const
 
unsigned nblock_types () const
 Return the number of block types. More...
 
unsigned ndof_types () const
 Return the total number of DOF types. More...
 
const Meshmesh_pt (const unsigned &i) const
 
unsigned nmesh () const
 
int block_number (const unsigned &i_dof) const
 Return the block number corresponding to a global index i_dof. More...
 
int index_in_block (const unsigned &i_dof) const
 
const LinearAlgebraDistributionblock_distribution_pt (const unsigned &b) const
 Access function to the block distributions (const version). More...
 
LinearAlgebraDistributionblock_distribution_pt (const unsigned b)
 Access function to the block distributions (non-const version). More...
 
LinearAlgebraDistributiondof_block_distribution_pt (const unsigned &b)
 Access function to the dof-level block distributions. More...
 
const LinearAlgebraDistributionmaster_distribution_pt () const
 
unsigned ndof_types_in_mesh (const unsigned &i) const
 
bool is_subsidiary_block_preconditioner () const
 
bool is_master_block_preconditioner () const
 
void set_block_output_to_files (const std::string &basefilename)
 
void disable_block_output_to_files ()
 Turn off output of blocks (by clearing the basefilename string). More...
 
bool block_output_on () const
 Test if output of blocks is on or not. More...
 
void output_blocks_to_files (const std::string &basefilename, const unsigned &precision=8) const
 
void post_block_matrix_assembly_partial_clear ()
 
BlockPreconditioner< CRDoubleMatrix > * master_block_preconditioner_pt () const
 Access function to the master block preconditioner pt. More...
 
void clear_block_preconditioner_base ()
 
void document ()
 
Vector< Vector< unsigned > > doftype_coarsen_map_fine () const
 
Vector< unsignedget_fine_grain_dof_types_in (const unsigned &i) const
 
unsigned nfine_grain_dof_types_in (const unsigned &i) const
 
MapMatrix< unsigned, CRDoubleMatrix * > replacement_dof_block_pt () const
 Access function to the replaced dof-level blocks. More...
 
void setup_matrix_vector_product (MatrixVectorProduct *matvec_prod_pt, CRDoubleMatrix *block_pt, const Vector< unsigned > &block_col_indices)
 
void setup_matrix_vector_product (MatrixVectorProduct *matvec_prod_pt, CRDoubleMatrix *block_pt, const unsigned &block_col_index)
 
void internal_get_block_ordered_preconditioner_vector (const DoubleVector &v, DoubleVector &w) const
 
void internal_return_block_ordered_preconditioner_vector (const DoubleVector &w, DoubleVector &v) const
 
unsigned internal_nblock_types () const
 
unsigned internal_ndof_types () const
 
void internal_return_block_vector (const unsigned &n, const DoubleVector &b, DoubleVector &v) const
 
void internal_get_block_vector (const unsigned &n, const DoubleVector &v, DoubleVector &b) const
 
void internal_get_block_vectors (const Vector< unsigned > &block_vec_number, const DoubleVector &v, Vector< DoubleVector > &s) const
 
void internal_get_block_vectors (const DoubleVector &v, Vector< DoubleVector > &s) const
 
void internal_return_block_vectors (const Vector< unsigned > &block_vec_number, const Vector< DoubleVector > &s, DoubleVector &v) const
 
void internal_return_block_vectors (const Vector< DoubleVector > &s, DoubleVector &v) const
 
void internal_get_block (const unsigned &i, const unsigned &j, CRDoubleMatrix &output_block) const
 
void internal_get_block (const unsigned &block_i, const unsigned &block_j, CRDoubleMatrix &output_block) const
 
int internal_block_number (const unsigned &i_dof) const
 
int internal_index_in_block (const unsigned &i_dof) const
 
const LinearAlgebraDistributioninternal_block_distribution_pt (const unsigned &b) const
 Access function to the internal block distributions. More...
 
void insert_auxiliary_block_distribution (const Vector< unsigned > &block_vec_number, LinearAlgebraDistribution *dist_pt)
 
void block_matrix_test (const unsigned &i, const unsigned &j, const CRDoubleMatrix *block_matrix_pt) const
 
int get_index_of_value (const Vector< myType > &vec, const myType val, const bool sorted=false) const
 
- Public Member Functions inherited from oomph::Preconditioner
 Preconditioner ()
 Constructor. More...
 
 Preconditioner (const Preconditioner &)=delete
 Broken copy constructor. More...
 
void operator= (const Preconditioner &)=delete
 Broken assignment operator. More...
 
virtual ~Preconditioner ()
 Destructor (empty) More...
 
virtual void preconditioner_solve_transpose (const DoubleVector &r, DoubleVector &z)
 
void setup (DoubleMatrixBase *matrix_pt)
 
void setup (const Problem *problem_pt, DoubleMatrixBase *matrix_pt)
 
void enable_silent_preconditioner_setup ()
 Set up the block preconditioner quietly! More...
 
void disable_silent_preconditioner_setup ()
 Be verbose in the block preconditioner setup. More...
 
virtual void set_matrix_pt (DoubleMatrixBase *matrix_pt)
 Set the matrix pointer. More...
 
virtual const OomphCommunicatorcomm_pt () const
 Get function for comm pointer. More...
 
virtual void set_comm_pt (const OomphCommunicator *const comm_pt)
 Set the communicator pointer. More...
 
double setup_time () const
 Returns the time to setup the preconditioner. More...
 
virtual void turn_into_subsidiary_block_preconditioner (BlockPreconditioner< CRDoubleMatrix > *master_block_prec_pt, const Vector< unsigned > &doftype_in_master_preconditioner_coarse)
 
virtual void turn_into_subsidiary_block_preconditioner (BlockPreconditioner< CRDoubleMatrix > *master_block_prec_pt, const Vector< unsigned > &doftype_in_master_preconditioner_coarse, const Vector< Vector< unsigned >> &doftype_coarsen_map_coarse)
 

Private Member Functions

void update (const unsigned &k, const Vector< Vector< double >> &H, const Vector< double > &s, const Vector< DoubleVector > &v, const DoubleVector &block_x_with_size_of_full_x, DoubleVector &x)
 
void generate_plane_rotation (double &dx, double &dy, double &cs, double &sn)
 
void apply_plane_rotation (double &dx, double &dy, double &cs, double &sn)
 
void update (const unsigned &k, const Vector< Vector< double >> &H, const Vector< double > &s, const Vector< DoubleVector > &v, const DoubleVector &block_x_with_size_of_full_x, DoubleVector &x)
 
void generate_plane_rotation (double &dx, double &dy, double &cs, double &sn)
 
void apply_plane_rotation (double &dx, double &dy, double &cs, double &sn)
 

Private Attributes

CRDoubleMatrixMatrix_pt
 Pointer to matrix. More...
 
SpaceTimeNavierStokesSubsidiaryPreconditionerNavier_stokes_subsidiary_preconditioner_pt
 Pointer to the preconditioner for the block matrix. More...
 
unsigned Iterations
 Number of iterations taken. More...
 
bool Compute_memory_statistics
 
double Memory_usage_in_bytes
 
bool Preconditioner_has_been_setup
 
bool Preconditioner_LHS
 

Additional Inherited Members

- Protected Member Functions inherited from oomph::DistributableLinearAlgebraObject
void clear_distribution ()
 
- Protected Member Functions inherited from oomph::BlockPreconditioner< CRDoubleMatrix >
void set_nmesh (const unsigned &n)
 
void set_mesh (const unsigned &i, const Mesh *const mesh_pt, const bool &allow_multiple_element_type_in_mesh=false)
 
void set_replacement_dof_block (const unsigned &block_i, const unsigned &block_j, CRDoubleMatrix *replacement_dof_block_pt)
 
bool any_mesh_distributed () const
 
int internal_dof_number (const unsigned &i_dof) const
 
unsigned internal_index_in_dof (const unsigned &i_dof) const
 
unsigned internal_block_dimension (const unsigned &b) const
 
unsigned internal_dof_block_dimension (const unsigned &i) const
 
unsigned master_nrow () const
 
unsigned internal_master_dof_number (const unsigned &b) const
 
const LinearAlgebraDistributioninternal_preconditioner_matrix_distribution_pt () const
 
const LinearAlgebraDistributionpreconditioner_matrix_distribution_pt () const
 
- Protected Attributes inherited from oomph::IterativeLinearSolver
bool Doc_convergence_history
 
std::ofstream Output_file_stream
 Output file stream for convergence history. More...
 
double Tolerance
 Convergence tolerance. More...
 
unsigned Max_iter
 Maximum number of iterations. More...
 
PreconditionerPreconditioner_pt
 Pointer to the preconditioner. More...
 
double Jacobian_setup_time
 Jacobian setup time. More...
 
double Solution_time
 linear solver solution time More...
 
double Preconditioner_setup_time
 Preconditioner setup time. More...
 
bool Setup_preconditioner_before_solve
 
bool Throw_error_after_max_iter
 
bool Use_iterative_solver_as_preconditioner
 Use the iterative solver as preconditioner. More...
 
bool First_time_solve_when_used_as_preconditioner
 
- Protected Attributes inherited from oomph::LinearSolver
bool Enable_resolve
 
bool Doc_time
 Boolean flag that indicates whether the time taken. More...
 
bool Compute_gradient
 
bool Gradient_has_been_computed
 flag that indicates whether the gradient was computed or not More...
 
DoubleVector Gradient_for_glob_conv_newton_solve
 
- Protected Attributes inherited from oomph::BlockPreconditioner< CRDoubleMatrix >
MapMatrix< unsigned, CRDoubleMatrix * > Replacement_dof_block_pt
 The replacement dof-level blocks. More...
 
Vector< LinearAlgebraDistribution * > Block_distribution_pt
 The distribution for the blocks. More...
 
Vector< Vector< unsigned > > Block_to_dof_map_coarse
 
Vector< Vector< unsigned > > Block_to_dof_map_fine
 Mapping for the block types to the most fine grain dof types. More...
 
Vector< Vector< unsigned > > Doftype_coarsen_map_coarse
 
Vector< Vector< unsigned > > Doftype_coarsen_map_fine
 
Vector< LinearAlgebraDistribution * > Internal_block_distribution_pt
 Storage for the default distribution for each internal block. More...
 
Vector< LinearAlgebraDistribution * > Dof_block_distribution_pt
 
Vector< unsignedAllow_multiple_element_type_in_mesh
 
Vector< const Mesh * > Mesh_pt
 
Vector< unsignedNdof_types_in_mesh
 
unsigned Internal_nblock_types
 
unsigned Internal_ndof_types
 
- Protected Attributes inherited from oomph::Preconditioner
bool Silent_preconditioner_setup
 Boolean to indicate whether or not the build should be done silently. More...
 
std::ostream * Stream_pt
 Pointer to the output stream – defaults to std::cout. More...
 
- Static Protected Attributes inherited from oomph::IterativeLinearSolver
static IdentityPreconditioner Default_preconditioner
 

Detailed Description

The block preconditioner form of GMRES. This version extracts the blocks from the global systems and assembles the system by concatenating all the matrices together

Constructor & Destructor Documentation

◆ GMRESBlockPreconditioner() [1/4]

oomph::GMRESBlockPreconditioner::GMRESBlockPreconditioner ( )
inline

Constructor (empty)

251  : BlockPreconditioner<CRDoubleMatrix>(),
252  Matrix_pt(0),
254  Iterations(0),
256  Preconditioner_LHS(false)
257  {
258  // By default, don't store the memory statistics of this preconditioner
260 
261  // Initialise the value of Memory_usage_in_bytes
262  Memory_usage_in_bytes = 0.0;
263  } // End of GMRESBlockPreconditioner
double Memory_usage_in_bytes
Definition: general_purpose_space_time_subsidiary_block_preconditioner.h:590
SpaceTimeNavierStokesSubsidiaryPreconditioner * Navier_stokes_subsidiary_preconditioner_pt
Pointer to the preconditioner for the block matrix.
Definition: general_purpose_space_time_subsidiary_block_preconditioner.h:579
bool Compute_memory_statistics
Definition: general_purpose_space_time_subsidiary_block_preconditioner.h:586
bool Preconditioner_has_been_setup
Definition: general_purpose_space_time_subsidiary_block_preconditioner.h:594
unsigned Iterations
Number of iterations taken.
Definition: general_purpose_space_time_subsidiary_block_preconditioner.h:582
bool Preconditioner_LHS
Definition: general_purpose_space_time_subsidiary_block_preconditioner.h:598
CRDoubleMatrix * Matrix_pt
Pointer to matrix.
Definition: general_purpose_space_time_subsidiary_block_preconditioner.h:575

References Compute_memory_statistics, and Memory_usage_in_bytes.

◆ ~GMRESBlockPreconditioner() [1/2]

virtual oomph::GMRESBlockPreconditioner::~GMRESBlockPreconditioner ( )
inlinevirtual

Destructor.

267  {
268  // Call the auxiliary clean up function
269  this->clean_up_memory();
270  } // End of ~GMRESBlockPreconditioner
virtual void clean_up_memory()
Clean up the memory (empty for now...)
Definition: general_purpose_space_time_subsidiary_block_preconditioner.h:273

References clean_up_memory().

◆ GMRESBlockPreconditioner() [2/4]

oomph::GMRESBlockPreconditioner::GMRESBlockPreconditioner ( const GMRESBlockPreconditioner )
delete

Broken copy constructor.

◆ GMRESBlockPreconditioner() [3/4]

oomph::GMRESBlockPreconditioner::GMRESBlockPreconditioner ( )
inline

Constructor (empty)

258  : BlockPreconditioner<CRDoubleMatrix>(),
259  Matrix_pt(0),
261  Iterations(0),
263  Preconditioner_LHS(false)
264  {
265  // By default, don't store the memory statistics of this preconditioner
267 
268  // Initialise the value of Memory_usage_in_bytes
269  Memory_usage_in_bytes = 0.0;
270  } // End of GMRESBlockPreconditioner

References Compute_memory_statistics, and Memory_usage_in_bytes.

◆ ~GMRESBlockPreconditioner() [2/2]

virtual oomph::GMRESBlockPreconditioner::~GMRESBlockPreconditioner ( )
inlinevirtual

Destructor.

274  {
275  // Call the auxiliary clean up function
276  this->clean_up_memory();
277  } // End of ~GMRESBlockPreconditioner

References clean_up_memory().

◆ GMRESBlockPreconditioner() [4/4]

oomph::GMRESBlockPreconditioner::GMRESBlockPreconditioner ( const GMRESBlockPreconditioner )
delete

Broken copy constructor.

Member Function Documentation

◆ apply_plane_rotation() [1/2]

void oomph::GMRESBlockPreconditioner::apply_plane_rotation ( double dx,
double dy,
double cs,
double sn 
)
inlineprivate

Helper function: Apply plane rotation. This is done using the update:

\[ \begin{bmatrix} dx \newline dy \end{bmatrix} \leftarrow \begin{bmatrix} \cos\theta & \sin\theta \newline -\sin\theta & \cos\theta \end{bmatrix} \begin{bmatrix} dx \newline dy \end{bmatrix}. \]

563  {
564  // Calculate the value of dx but don't update it yet
565  double temp = cs * dx + sn * dy;
566 
567  // Set the value of dy
568  dy = -sn * dx + cs * dy;
569 
570  // Set the value of dx using the correct values of dx and dy
571  dx = temp;
572  } // End of apply_plane_rotation

Referenced by preconditioner_solve().

◆ apply_plane_rotation() [2/2]

void oomph::GMRESBlockPreconditioner::apply_plane_rotation ( double dx,
double dy,
double cs,
double sn 
)
inlineprivate

Helper function: Apply plane rotation. This is done using the update:

\[ \begin{bmatrix} dx \newline dy \end{bmatrix} \leftarrow \begin{bmatrix} \cos\theta & \sin\theta \newline -\sin\theta & \cos\theta \end{bmatrix} \begin{bmatrix} dx \newline dy \end{bmatrix}. \]

570  {
571  // Calculate the value of dx but don't update it yet
572  double temp = cs * dx + sn * dy;
573 
574  // Set the value of dy
575  dy = -sn * dx + cs * dy;
576 
577  // Set the value of dx using the correct values of dx and dy
578  dx = temp;
579  } // End of apply_plane_rotation

◆ clean_up_memory() [1/2]

virtual void oomph::GMRESBlockPreconditioner::clean_up_memory ( )
inlinevirtual

Clean up the memory (empty for now...)

Reimplemented from oomph::LinearSolver.

274  {
275  // If the block preconditioner has been set up previously
277  {
278  // Delete the subsidiary preconditioner
280 
281  // Make it a null pointer
283 
284  // Delete the matrix!
285  delete Matrix_pt;
286 
287  // Make it a null pointer
288  Matrix_pt = 0;
289  }
290  } // End of clean_up_memory

References Matrix_pt, Navier_stokes_subsidiary_preconditioner_pt, and Preconditioner_has_been_setup.

Referenced by setup(), and ~GMRESBlockPreconditioner().

◆ clean_up_memory() [2/2]

virtual void oomph::GMRESBlockPreconditioner::clean_up_memory ( )
inlinevirtual

Clean up the memory (empty for now...)

Reimplemented from oomph::LinearSolver.

281  {
282  // If the block preconditioner has been set up previously
284  {
285  // Delete the subsidiary preconditioner
287 
288  // Make it a null pointer
290 
291  // Delete the matrix!
292  delete Matrix_pt;
293 
294  // Make it a null pointer
295  Matrix_pt = 0;
296  }
297  } // End of clean_up_memory

References Matrix_pt, Navier_stokes_subsidiary_preconditioner_pt, and Preconditioner_has_been_setup.

◆ disable_doc_memory_statistics()

void oomph::GMRESBlockPreconditioner::disable_doc_memory_statistics ( )
inline

Don't document the memory usage!

Set the appropriate flag to false

356  {
359  } // End of disable_doc_memory_statistics

References Compute_memory_statistics.

◆ disable_doc_memory_usage()

void oomph::GMRESBlockPreconditioner::disable_doc_memory_usage ( )
inline

Don't document the memory usage!

Set the appropriate flag to false

349  {
352  } // End of disable_doc_memory_usage

References Compute_memory_statistics.

◆ enable_doc_memory_statistics()

void oomph::GMRESBlockPreconditioner::enable_doc_memory_statistics ( )
inline

Document the memory usage.

Set the appropriate flag to true

348  {
351  } // End of enable_doc_memory_statistics

References Compute_memory_statistics.

◆ enable_doc_memory_usage()

void oomph::GMRESBlockPreconditioner::enable_doc_memory_usage ( )
inline

Document the memory usage.

Set the appropriate flag to true

341  {
344  } // End of enable_doc_memory_usage

References Compute_memory_statistics.

◆ generate_plane_rotation() [1/2]

void oomph::GMRESBlockPreconditioner::generate_plane_rotation ( double dx,
double dy,
double cs,
double sn 
)
inlineprivate

Helper function: Generate a plane rotation. This is done by finding the values of \( \cos(\theta) \) (i.e. cs) and \sin(\theta) (i.e. sn) such that:

\[ \begin{bmatrix} \cos\theta & \sin\theta \newline -\sin\theta & \cos\theta \end{bmatrix} \begin{bmatrix} dx \newline dy \end{bmatrix} = \begin{bmatrix} r \newline 0 \end{bmatrix}, \]

where \( r=\sqrt{pow(dx,2)+pow(dy,2)} \). The values of a and b are given by:

\[ \cos\theta&=\dfrac{dx}{\sqrt{pow(dx,2)+pow(dy,2)}}, \]

and

\[ \sin\theta&=\dfrac{dy}{\sqrt{pow(dx,2)+pow(dy,2)}}. \]

Taken from: Saad Y."Iterative methods for sparse linear systems", p.192

518  {
519  // If dy=0 then we do not need to apply a rotation
520  if (dy == 0.0)
521  {
522  // Using theta=0 gives cos(theta)=1
523  cs = 1.0;
524 
525  // Using theta=0 gives sin(theta)=0
526  sn = 0.0;
527  }
528  // If dx or dy is large using the normal form of calculting cs and sn
529  // is naive since this may overflow or underflow so instead we calculate
530  // r=sqrt(pow(dx,2)+pow(dy,2)) by using r=|dy|sqrt(1+pow(dx/dy,2)) if
531  // |dy|>|dx| [see <A
532  // HREF=https://en.wikipedia.org/wiki/Hypot">Hypot</A>.].
533  else if (fabs(dy) > fabs(dx))
534  {
535  // Since |dy|>|dx| calculate the ratio dx/dy
536  double temp = dx / dy;
537 
538  // Calculate sin(theta)=dy/sqrt(pow(dx,2)+pow(dy,2))
539  sn = 1.0 / sqrt(1.0 + temp * temp);
540 
541  // Calculate cos(theta)=dx/sqrt(pow(dx,2)+pow(dy,2))=(dx/dy)*sin(theta)
542  cs = temp * sn;
543  }
544  // Otherwise, we have |dx|>=|dy| so to, again, avoid overflow or underflow
545  // calculate the values of cs and sn using the method above
546  else
547  {
548  // Since |dx|>=|dy| calculate the ratio dy/dx
549  double temp = dy / dx;
550 
551  // Calculate cos(theta)=dx/sqrt(pow(dx,2)+pow(dy,2))
552  cs = 1.0 / sqrt(1.0 + temp * temp);
553 
554  // Calculate sin(theta)=dy/sqrt(pow(dx,2)+pow(dy,2))=(dy/dx)*cos(theta)
555  sn = temp * cs;
556  }
557  } // End of generate_plane_rotation
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
Real fabs(const Real &a)
Definition: boostmultiprec.cpp:117

References boost::multiprecision::fabs(), and sqrt().

Referenced by preconditioner_solve().

◆ generate_plane_rotation() [2/2]

void oomph::GMRESBlockPreconditioner::generate_plane_rotation ( double dx,
double dy,
double cs,
double sn 
)
inlineprivate

Helper function: Generate a plane rotation. This is done by finding the values of \( \cos(\theta) \) (i.e. cs) and \sin(\theta) (i.e. sn) such that:

\[ \begin{bmatrix} \cos\theta & \sin\theta \newline -\sin\theta & \cos\theta \end{bmatrix} \begin{bmatrix} dx \newline dy \end{bmatrix} = \begin{bmatrix} r \newline 0 \end{bmatrix}, \]

where \( r=\sqrt{pow(dx,2)+pow(dy,2)} \). The values of a and b are given by:

\[ \cos\theta&=\dfrac{dx}{\sqrt{pow(dx,2)+pow(dy,2)}}, \]

and

\[ \sin\theta&=\dfrac{dy}{\sqrt{pow(dx,2)+pow(dy,2)}}. \]

Taken from: Saad Y."Iterative methods for sparse linear systems", p.192

525  {
526  // If dy=0 then we do not need to apply a rotation
527  if (dy == 0.0)
528  {
529  // Using theta=0 gives cos(theta)=1
530  cs = 1.0;
531 
532  // Using theta=0 gives sin(theta)=0
533  sn = 0.0;
534  }
535  // If dx or dy is large using the normal form of calculting cs and sn
536  // is naive since this may overflow or underflow so instead we calculate
537  // r=sqrt(pow(dx,2)+pow(dy,2)) by using r=|dy|sqrt(1+pow(dx/dy,2)) if
538  // |dy|>|dx| [see <A
539  // HREF=https://en.wikipedia.org/wiki/Hypot">Hypot</A>.].
540  else if (fabs(dy) > fabs(dx))
541  {
542  // Since |dy|>|dx| calculate the ratio dx/dy
543  double temp = dx / dy;
544 
545  // Calculate sin(theta)=dy/sqrt(pow(dx,2)+pow(dy,2))
546  sn = 1.0 / sqrt(1.0 + temp * temp);
547 
548  // Calculate cos(theta)=dx/sqrt(pow(dx,2)+pow(dy,2))=(dx/dy)*sin(theta)
549  cs = temp * sn;
550  }
551  // Otherwise, we have |dx|>=|dy| so to, again, avoid overflow or underflow
552  // calculate the values of cs and sn using the method above
553  else
554  {
555  // Since |dx|>=|dy| calculate the ratio dy/dx
556  double temp = dy / dx;
557 
558  // Calculate cos(theta)=dx/sqrt(pow(dx,2)+pow(dy,2))
559  cs = 1.0 / sqrt(1.0 + temp * temp);
560 
561  // Calculate sin(theta)=dy/sqrt(pow(dx,2)+pow(dy,2))=(dy/dx)*cos(theta)
562  sn = temp * cs;
563  }
564  } // End of generate_plane_rotation

References boost::multiprecision::fabs(), and sqrt().

◆ get_memory_usage_in_bytes() [1/2]

double oomph::GMRESBlockPreconditioner::get_memory_usage_in_bytes ( )
inline

Get the memory statistics.

357  {
358  // Has the preconditioner even been set up yet?
360  {
361  // Were we meant to compute the statistics?
363  {
364  // Return the appropriate variable value
365  return Memory_usage_in_bytes;
366  }
367  else
368  {
369  // Allocate storage for an output stream
370  std::ostringstream warning_message_stream;
371 
372  // Create a warning message
373  warning_message_stream
374  << "The memory statistics have not been calculated "
375  << "so I'm returning\nthe value zero." << std::endl;
376 
377  // Give the user a warning
378  OomphLibWarning(warning_message_stream.str(),
381 
382  // Return the value zero
383  return 0.0;
384  }
385  }
386  // If the preconditioner hasn't been set up yet
387  else
388  {
389  // Allocate storage for an output stream
390  std::ostringstream warning_message_stream;
391 
392  // Create a warning message
393  warning_message_stream
394  << "The preconditioner hasn't even been set up yet "
395  << "so I'm returning\nthe value zero." << std::endl;
396 
397  // Give the user a warning
398  OomphLibWarning(warning_message_stream.str(),
401 
402  // Return the value zero
403  return 0.0;
404  } // if (Preconditioner_has_been_setup)
405  } // End of get_memory_usage_in_bytes
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References Compute_memory_statistics, Memory_usage_in_bytes, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and Preconditioner_has_been_setup.

Referenced by oomph::BandedBlockTriangularPreconditioner< MATRIX >::setup().

◆ get_memory_usage_in_bytes() [2/2]

double oomph::GMRESBlockPreconditioner::get_memory_usage_in_bytes ( )
inline

Get the memory statistics.

364  {
365  // Has the preconditioner even been set up yet?
367  {
368  // Were we meant to compute the statistics?
370  {
371  // Return the appropriate variable value
372  return Memory_usage_in_bytes;
373  }
374  else
375  {
376  // Allocate storage for an output stream
377  std::ostringstream warning_message_stream;
378 
379  // Create a warning message
380  warning_message_stream
381  << "The memory statistics have not been calculated "
382  << "so I'm returning\nthe value zero." << std::endl;
383 
384  // Give the user a warning
385  OomphLibWarning(warning_message_stream.str(),
388 
389  // Return the value zero
390  return 0.0;
391  }
392  }
393  // If the preconditioner hasn't been set up yet
394  else
395  {
396  // Allocate storage for an output stream
397  std::ostringstream warning_message_stream;
398 
399  // Create a warning message
400  warning_message_stream
401  << "The preconditioner hasn't even been set up yet "
402  << "so I'm returning\nthe value zero." << std::endl;
403 
404  // Give the user a warning
405  OomphLibWarning(warning_message_stream.str(),
408 
409  // Return the value zero
410  return 0.0;
411  } // if (Preconditioner_has_been_setup)
412  } // End of get_memory_usage_in_bytes

References Compute_memory_statistics, Memory_usage_in_bytes, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and Preconditioner_has_been_setup.

◆ iterations() [1/2]

unsigned oomph::GMRESBlockPreconditioner::iterations ( ) const
inlinevirtual

Handle to the number of iterations taken.

Implements oomph::IterativeLinearSolver.

321  {
322  // Return the number of iterations
323  return Iterations;
324  } // End of iterations

References Iterations.

◆ iterations() [2/2]

unsigned oomph::GMRESBlockPreconditioner::iterations ( ) const
inlinevirtual

Handle to the number of iterations taken.

Implements oomph::IterativeLinearSolver.

328  {
329  // Return the number of iterations
330  return Iterations;
331  } // End of iterations

References Iterations.

◆ navier_stokes_subsidiary_preconditioner_pt() [1/2]

SpaceTimeNavierStokesSubsidiaryPreconditioner* oomph::GMRESBlockPreconditioner::navier_stokes_subsidiary_preconditioner_pt ( ) const
inline

Handle to the Navier-Stokes subsidiary block preconditioner DRAIG: Make sure the desired const-ness is correct later...

412  {
413  // Return a pointer to the appropriate member data
415  } // End of navier_stokes_subsidiary_preconditioner_pt

References Navier_stokes_subsidiary_preconditioner_pt.

Referenced by oomph::BandedBlockTriangularPreconditioner< MATRIX >::setup().

◆ navier_stokes_subsidiary_preconditioner_pt() [2/2]

SpaceTimeNavierStokesSubsidiaryPreconditioner* oomph::GMRESBlockPreconditioner::navier_stokes_subsidiary_preconditioner_pt ( ) const
inline

Handle to the Navier-Stokes subsidiary block preconditioner DRAIG: Make sure the desired const-ness is correct later...

419  {
420  // Return a pointer to the appropriate member data
422  } // End of navier_stokes_subsidiary_preconditioner_pt

References Navier_stokes_subsidiary_preconditioner_pt.

◆ operator=() [1/2]

void oomph::GMRESBlockPreconditioner::operator= ( const GMRESBlockPreconditioner )
delete

Broken assignment operator.

◆ operator=() [2/2]

void oomph::GMRESBlockPreconditioner::operator= ( const GMRESBlockPreconditioner )
delete

Broken assignment operator.

◆ preconditioner_solve() [1/2]

void oomph::GMRESBlockPreconditioner::preconditioner_solve ( const DoubleVector r,
DoubleVector z 
)
virtual

Apply preconditioner to r.

Preconditioner solve for the GMRES block preconditioner.

Implements oomph::Preconditioner.

731  {
732  // Get the number of block types
733  unsigned n_block_types = this->nblock_types();
734 
735  // If there is more than one block type (there shouldn't be!)
736  if (n_block_types != 1)
737  {
738  // Throw an error
739  throw OomphLibError("Can only deal with one dof type!",
742  }
743 
744  // Allocate space for the solution blocks
745  Vector<DoubleVector> block_z(n_block_types);
746 
747  // Allocate space for the residual blocks
748  Vector<DoubleVector> block_r(n_block_types);
749 
750  // Get the reordered RHS vector
751  this->get_block_vectors(rhs, block_r);
752 
753  // Get the reordered solution vector
754  this->get_block_vectors(solution, block_z);
755 
756  // Initialise the entries in the solution vector to zero
757  block_z[0].initialise(0.0);
758 
759  // Get number of dofs
760  unsigned n_dof = block_r[0].nrow();
761 
762  // Time solver
763  double t_start = TimingHelpers::timer();
764 
765  // Relative residual
766  double resid;
767 
768  // Iteration counter
769  unsigned iter = 1;
770 
771  // Initialise vectors
772  Vector<double> s(n_dof + 1, 0);
773  Vector<double> cs(n_dof + 1);
774  Vector<double> sn(n_dof + 1);
775  DoubleVector w(block_r[0].distribution_pt(), 0.0);
776 
777  // Storage for the time taken for all preconditioner applications
778  double t_prec_application_total = 0.0;
779 
780  // Storage for the RHS vector
781  DoubleVector r(block_r[0].distribution_pt(), 0.0);
782 
783  // If we're using LHS preconditioning then solve Mr=b-Jx for r (assumes x=0)
784  if (Preconditioner_LHS)
785  {
786  // Initialise timer
787  double t_prec_application_start = TimingHelpers::timer();
788 
789  // This is pretty inefficient but there is no other way to do this with
790  // block subsidiary preconditioners as far as I can tell because they
791  // demand to have the full r and z vectors...
792  DoubleVector block_z_with_size_of_full_z(rhs.distribution_pt(), 0.0);
793  DoubleVector r_updated(rhs.distribution_pt(), 0.0);
794 
795  // Reorder the entries in block_r[0] and put them back into the
796  // global-sized vector. The subsidiary preconditioner should only
797  // operate on the dofs that this preconditioner operates on so
798  // don't worry about all the other entries
799  this->return_block_vector(0, block_r[0], r_updated);
800 
801  // Solve on the global-sized vectors
803  r_updated, block_z_with_size_of_full_z);
804 
805  // Now grab the part of the solution associated with this preconditioner
806  this->get_block_vector(0, block_z_with_size_of_full_z, block_z[0]);
807 
808  // Doc time for setup of preconditioner
809  double t_prec_application_end = TimingHelpers::timer();
810 
811  // Update the preconditioner application time total
812  t_prec_application_total +=
813  (t_prec_application_end - t_prec_application_start);
814  }
815  // If we're using RHS preconditioning, do nothing to the actual RHS vector
816  else
817  {
818  // Copy the entries into r
819  r = block_r[0];
820  }
821 
822  // Calculate the initial residual norm (assumes x=0 initially)
823  double normb = r.norm();
824 
825  // Set beta (the initial residual)
826  double beta = normb;
827 
828  // Compute initial relative residual
829  if (normb == 0.0)
830  {
831  // To avoid dividing by zero, set normb to 1
832  normb = 1;
833  }
834 
835  // Now calculate the relative residual norm
836  resid = beta / normb;
837 
838  // If required, document convergence history to screen or file (if
839  // stream is open)
841  {
842  // If a file has not been provided to output to
843  if (!Output_file_stream.is_open())
844  {
845  // Output the initial relative residual norm to screen
846  oomph_info << 0 << " " << resid << std::endl;
847  }
848  // If there is a file provided to output to
849  else
850  {
851  // Output the initial relative residual norm to file
852  Output_file_stream << 0 << " " << resid << std::endl;
853  }
854  } // if (Doc_convergence_history)
855 
856  // If GMRES converges immediately
857  if (resid <= Tolerance)
858  {
859  // If the user wishes GMRES to output information about the solve to
860  // screen
861  if (Doc_time)
862  {
863  // Tell the user
864  oomph_info << "GMRES block preconditioner converged immediately. "
865  << "Normalised residual norm: " << resid << std::endl;
866  }
867 
868  // Now reorder the values in block_z[0] and put them back into the
869  // global solution vector
870  this->return_block_vector(0, block_z[0], solution);
871 
872  // Doc time for solver
873  double t_end = TimingHelpers::timer();
874  Solution_time = t_end - t_start;
875 
876  // If the user wishes GMRES to output information about the solve to
877  // screen
878  if (Doc_time)
879  {
880  // Tell the user
881  oomph_info << "Time for all preconditioner applications [sec]: "
882  << t_prec_application_total
883  << "\nTotal time for solve with GMRES block preconditioner "
884  << "[sec]: " << Solution_time << std::endl;
885  }
886 
887  // We're finished; end here!
888  return;
889  } // if (resid<=Tolerance)
890 
891  // Initialise vector of orthogonal basis vectors, v
892  Vector<DoubleVector> v(n_dof + 1);
893 
894  // Initialise the upper Hessenberg matrix H.
895  // NOTE: For implementation purposes the upper hessenberg matrix indices
896  // are swapped so the matrix is effectively transposed
897  Vector<Vector<double>> H(n_dof + 1);
898 
899  // Loop as many times as we're allowed
900  while (iter <= Max_iter)
901  {
902  // Copy the entries of the residual vector, r, into v[0]
903  v[0] = r;
904 
905  // Now update the zeroth basis vector, v[0], to have values r/beta
906  v[0] /= beta;
907 
908  // Storage for ...?
909  s[0] = beta;
910 
911  // Inner iteration counter for restarted version (we don't actually use
912  // a restart in this implementation of GMRES...)
913  unsigned iter_restart;
914 
915  // Perform iterations
916  for (iter_restart = 0; iter_restart < n_dof && iter <= Max_iter;
917  iter_restart++, iter++)
918  {
919  // Resize next column of the upper Hessenberg matrix
920  H[iter_restart].resize(iter_restart + 2);
921 
922  // Solve for w inside the scope of these braces
923  {
924  // Temporary vector
925  DoubleVector temp(block_r[0].distribution_pt(), 0.0);
926 
927  // If we're using LHS preconditioning solve Mw=Jv[i] for w
928  if (Preconditioner_LHS)
929  {
930  // Calculate temp=Jv[i]
931  Matrix_pt->multiply(v[iter_restart], temp);
932 
933  // Get the current time
934  double t_prec_application_start = TimingHelpers::timer();
935 
936  // This is pretty inefficient but there is no other way to do this
937  // with block sub preconditioners as far as I can tell because they
938  // demand to have the full r and z vectors...
939  DoubleVector block_z_with_size_of_full_z(rhs.distribution_pt(),
940  0.0);
941  DoubleVector r_updated(rhs.distribution_pt(), 0.0);
942 
943  // Put the values in temp into the global-sized vector
944  this->return_block_vector(0, temp, r_updated);
945 
946  // Apply the NSSP to the global-sized vectors (this will extract
947  // the appropriate sub-vectors and solve on the reduced system)
949  r_updated, block_z_with_size_of_full_z);
950 
951  // Now grab the part of the solution associated with this
952  // preconditioner
953  this->get_block_vector(0, block_z_with_size_of_full_z, w);
954 
955  // End timer
956  double t_prec_application_end = TimingHelpers::timer();
957 
958  // Update the preconditioner application time total
959  t_prec_application_total +=
960  (t_prec_application_end - t_prec_application_start);
961  }
962  // If we're using RHS preconditioning solve
963  else
964  {
965  // Initialise timer
966  double t_prec_application_start = TimingHelpers::timer();
967 
968  // This is pretty inefficient but there is no other way to do this
969  // with block sub preconditioners as far as I can tell because they
970  // demand to have the full r and z vectors...
971  DoubleVector block_z_with_size_of_full_z(rhs.distribution_pt());
972  DoubleVector r_updated(rhs.distribution_pt());
973 
974  // Put the values in v[iter_restart] back into the global-sized
975  // vector
976  this->return_block_vector(0, v[iter_restart], r_updated);
977 
978  // Solve on the global-sized vectors
980  r_updated, block_z_with_size_of_full_z);
981 
982  // Now grab the part of the solution associated with this
983  // preconditioner
984  this->get_block_vector(0, block_z_with_size_of_full_z, temp);
985 
986  // Doc time for setup of preconditioner
987  double t_prec_application_end = TimingHelpers::timer();
988 
989  // Update the preconditioner application time total
990  t_prec_application_total +=
991  (t_prec_application_end - t_prec_application_start);
992 
993  // Calculate w=Jv_m where v_m=M^{-1}v
994  Matrix_pt->multiply(temp, w);
995  }
996  } // End of solve for w
997 
998  // Get a pointer to the values in w
999  double* w_pt = w.values_pt();
1000 
1001  // Loop over the columns of the (transposed) Hessenberg matrix
1002  for (unsigned k = 0; k <= iter_restart; k++)
1003  {
1004  // Initialise the entry in the upper Hessenberg matrix
1005  H[iter_restart][k] = 0.0;
1006 
1007  // Get the pointer to the values of the k-th basis vector
1008  double* vk_pt = v[k].values_pt();
1009 
1010  // Update H with the dot product of w and v[k]
1011  H[iter_restart][k] += w.dot(v[k]);
1012 
1013  // Loop over the entries in w and v[k] again
1014  for (unsigned i = 0; i < n_dof; i++)
1015  {
1016  // Now update the values in w
1017  w_pt[i] -= H[iter_restart][k] * vk_pt[i];
1018  }
1019  } // for (unsigned k=0;k<=iter_restart;k++)
1020 
1021  // Calculate the (iter_restart+1,iter_restart)-th entry in the upper
1022  // Hessenberg matrix (remember, H is actually the transpose of the
1023  // proper upper Hessenberg matrix)
1024  H[iter_restart][iter_restart + 1] = w.norm();
1025 
1026  // Build the (iter_restart+1)-th basis vector by copying w
1027  v[iter_restart + 1] = w;
1028 
1029  // Now rescale the basis vector
1030  v[iter_restart + 1] /= H[iter_restart][iter_restart + 1];
1031 
1032  // Loop over the columns of the transposed upper Hessenberg matrix
1033  for (unsigned k = 0; k < iter_restart; k++)
1034  {
1035  // Apply a Givens rotation to entries of H
1037  H[iter_restart][k], H[iter_restart][k + 1], cs[k], sn[k]);
1038  }
1039 
1040  // Now generate the cs and sn entries for a plane rotation
1041  generate_plane_rotation(H[iter_restart][iter_restart],
1042  H[iter_restart][iter_restart + 1],
1043  cs[iter_restart],
1044  sn[iter_restart]);
1045 
1046  // Use the newly generated entries in cs and sn to apply a Givens
1047  // rotation to those same entries
1048  apply_plane_rotation(H[iter_restart][iter_restart],
1049  H[iter_restart][iter_restart + 1],
1050  cs[iter_restart],
1051  sn[iter_restart]);
1052 
1053  // Now apply the Givens rotation to the entries in s
1054  apply_plane_rotation(s[iter_restart],
1055  s[iter_restart + 1],
1056  cs[iter_restart],
1057  sn[iter_restart]);
1058 
1059  // Compute the current residual
1060  beta = std::fabs(s[iter_restart + 1]);
1061 
1062  // Compute the relative residual norm
1063  resid = beta / normb;
1064 
1065  // If required, document the convergence history to screen or file
1067  {
1068  // If an output file has not been provided
1069  if (!Output_file_stream.is_open())
1070  {
1071  // Output the convergence history to screen
1072  oomph_info << iter << " " << resid << std::endl;
1073  }
1074  // An output file has been provided so output to that
1075  else
1076  {
1077  // Output the convergence history to file
1078  Output_file_stream << iter << " " << resid << std::endl;
1079  }
1080  } // if (Doc_convergence_history)
1081 
1082  // If the required tolerance was met
1083  if (resid < Tolerance)
1084  {
1085  // Storage for the global-sized solution vector. Strictly speaking
1086  // we could actually just use the vector, solution but this can be
1087  // done after we know we've implemented everything correctly...
1088  DoubleVector block_z_with_size_of_full_z(rhs.distribution_pt(), 0.0);
1089 
1090  // Take the current solution, reorder the entries appropriately
1091  // and stick them into the global sized vector
1092  this->return_block_vector(0, block_z[0], block_z_with_size_of_full_z);
1093 
1094  // This will update block_z[0] and won't touch the global-size vector
1095  // block_x_with_size_of_full_x. We're in charge of reordering the
1096  // entries and putting it in solution
1097  update(
1098  iter_restart, H, s, v, block_z_with_size_of_full_z, block_z[0]);
1099 
1100  // Now go into block_z[0], reorder the entries in the appropriate
1101  // manner and put them into the vector, solution
1102  this->return_block_vector(0, block_z[0], solution);
1103 
1104  // If the user wishes GMRES to document the convergence
1105  if (Doc_time)
1106  {
1107  // Document the convergence to screen
1108  oomph_info
1109  << "\nGMRES block preconditioner converged (1). Normalised "
1110  << "residual norm: " << resid
1111  << "\nNumber of iterations to convergence: " << iter << "\n"
1112  << std::endl;
1113  }
1114 
1115  // Get the current time
1116  double t_end = TimingHelpers::timer();
1117 
1118  // Calculate the time difference, i.e. the time taken for the whole
1119  // solve
1120  Solution_time = t_end - t_start;
1121 
1122  // Storage the iteration count
1123  Iterations = iter;
1124 
1125  // If the user wishes GMRES to document the convergence
1126  if (Doc_time)
1127  {
1128  // Document the convergence to screen
1129  oomph_info
1130  << "Time for all preconditioner applications [sec]: "
1131  << t_prec_application_total
1132  << "\nTotal time for solve with GMRES block preconditioner "
1133  << "[sec]: " << Solution_time << std::endl;
1134  }
1135 
1136  // We're done now; finish here
1137  return;
1138  } // if (resid<Tolerance)
1139  } // for (iter_restart=0;iter_restart<n_dof&&iter<=Max_iter;...
1140 
1141  // Update
1142  if (iter_restart > 0)
1143  {
1144  // Storage for the global-sized solution vector
1145  DoubleVector block_z_with_size_of_full_z(rhs.distribution_pt(), 0.0);
1146 
1147  // Take the current solution, reorder the entries appropriately
1148  // and stick them into the global sized vector
1149  this->return_block_vector(0, block_z[0], block_z_with_size_of_full_z);
1150 
1151  // Update the (reordered block) solution vector
1152  update(
1153  (iter_restart - 1), H, s, v, block_z_with_size_of_full_z, block_z[0]);
1154 
1155  // Now go into block_z[0], reorder the entries in the appropriate manner
1156  // and put them into the vector, solution
1157  this->return_block_vector(0, block_z[0], solution);
1158  }
1159 
1160  // Solve Mr=(b-Jx) for r
1161  {
1162  // Temporary vector to store b-Jx
1163  DoubleVector temp(block_r[0].distribution_pt(), 0.0);
1164 
1165  // Calculate temp=b-Jx
1166  Matrix_pt->residual(block_z[0], block_r[0], temp);
1167 
1168  // If we're using LHS preconditioning
1169  if (Preconditioner_LHS)
1170  {
1171  // Initialise timer
1172  double t_prec_application_start = TimingHelpers::timer();
1173 
1174  // This is pretty inefficient but there is no other way to do this
1175  // with block sub preconditioners as far as I can tell because they
1176  // demand to have the full r and z vectors...
1177  DoubleVector block_z_with_size_of_full_z(rhs.distribution_pt());
1178  DoubleVector r_updated(rhs.distribution_pt());
1179 
1180  // Reorder the entries of temp and put them into the global-sized
1181  // vector
1182  this->return_block_vector(0, temp, r_updated);
1183 
1184  // Solve on the global-sized vectors
1186  r_updated, block_z_with_size_of_full_z);
1187 
1188  // Now grab the part of the solution associated with this
1189  // preconditioner
1190  this->get_block_vector(0, block_z_with_size_of_full_z, r);
1191 
1192  // Doc time for setup of preconditioner
1193  double t_prec_application_end = TimingHelpers::timer();
1194 
1195  // Update the preconditioner application time total
1196  t_prec_application_total +=
1197  (t_prec_application_end - t_prec_application_start);
1198  }
1199  } // End of solve Mr=(b-Jx) for r
1200 
1201  // Compute the current residual norm
1202  beta = r.norm();
1203 
1204  // if relative residual within tolerance
1205  resid = beta / normb;
1206  if (resid < Tolerance)
1207  {
1208  // Now store the result in the global solution vector
1209  this->return_block_vector(0, block_z[0], solution);
1210 
1211  if (Doc_time)
1212  {
1213  oomph_info
1214  << "\nGMRES block preconditioner converged (2). Normalised "
1215  << "residual norm: " << resid
1216  << "\nNumber of iterations to convergence: " << iter << "\n"
1217  << std::endl;
1218  }
1219 
1220  // Doc time for solver
1221  double t_end = TimingHelpers::timer();
1222  Solution_time = t_end - t_start;
1223 
1224  Iterations = iter;
1225 
1226  if (Doc_time)
1227  {
1228  oomph_info
1229  << "Time for all preconditioner applications [sec]: "
1230  << t_prec_application_total
1231  << "\nTotal time for solve with GMRES block preconditioner "
1232  << "[sec]: " << Solution_time << std::endl;
1233  }
1234  return;
1235  }
1236  }
1237 
1238 
1239  // otherwise GMRES failed convergence
1240  oomph_info << "\nGMRES block preconditioner did not converge to required "
1241  << "tolerance! \nReturning with normalised residual norm: "
1242  << resid << "\nafter " << Max_iter << " iterations.\n"
1243  << std::endl;
1244 
1246  {
1247  std::ostringstream error_message_stream;
1248  error_message_stream << "Solver failed to converge and you requested an "
1249  << "error on convergence failures.";
1250  throw OomphLibError(error_message_stream.str(),
1253  }
1254  } // End of solve_helper
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
int i
Definition: BiCGSTAB_step_by_step.cpp:9
std::vector< double > DoubleVector
loads clump configuration
Definition: ClumpInput.h:26
MatrixXf H
Definition: HessenbergDecomposition_matrixH.cpp:4
RowVector3d w
Definition: Matrix_resize_int.cpp:3
void return_block_vector(const unsigned &n, const DoubleVector &b, DoubleVector &v) const
Definition: block_preconditioner.cc:4489
void get_block_vector(const unsigned &n, const DoubleVector &v, DoubleVector &b) const
Definition: block_preconditioner.cc:4186
unsigned nblock_types() const
Return the number of block types.
Definition: block_preconditioner.h:1670
void get_block_vectors(const Vector< unsigned > &block_vec_number, const DoubleVector &v, Vector< DoubleVector > &s) const
Definition: block_preconditioner.cc:2939
void multiply(const DoubleVector &x, DoubleVector &soln) const
Multiply the matrix by the vector x: soln=Ax.
Definition: matrices.cc:1782
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
Definition: linear_algebra_distribution.h:457
virtual void residual(const DoubleVector &x, const DoubleVector &b, DoubleVector &residual_)
Find the residual, i.e. r=b-Ax the residual.
Definition: matrices.h:326
void apply_plane_rotation(double &dx, double &dy, double &cs, double &sn)
Definition: general_purpose_space_time_subsidiary_block_preconditioner.h:562
void update(const unsigned &k, const Vector< Vector< double >> &H, const Vector< double > &s, const Vector< DoubleVector > &v, const DoubleVector &block_x_with_size_of_full_x, DoubleVector &x)
Definition: general_purpose_space_time_subsidiary_block_preconditioner.h:420
void generate_plane_rotation(double &dx, double &dy, double &cs, double &sn)
Definition: general_purpose_space_time_subsidiary_block_preconditioner.h:517
double Tolerance
Convergence tolerance.
Definition: iterative_linear_solver.h:239
bool Throw_error_after_max_iter
Definition: iterative_linear_solver.h:262
unsigned Max_iter
Maximum number of iterations.
Definition: iterative_linear_solver.h:242
double Solution_time
linear solver solution time
Definition: iterative_linear_solver.h:251
std::ofstream Output_file_stream
Output file stream for convergence history.
Definition: iterative_linear_solver.h:231
bool Doc_convergence_history
Definition: iterative_linear_solver.h:228
bool Doc_time
Boolean flag that indicates whether the time taken.
Definition: linear_solver.h:77
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to r.
Definition: general_purpose_space_time_subsidiary_block_preconditioner.cc:482
RealScalar s
Definition: level1_cplx_impl.h:130
Scalar beta
Definition: level2_cplx_impl.h:36
char char char int int * k
Definition: level2_impl.h:374
void solution(const Vector< double > &x, Vector< double > &u)
Definition: two_d_biharmonic.cc:113
r
Definition: UniformPSDSelfTest.py:20
double timer()
returns the time in seconds after some point in past
Definition: oomph_utilities.cc:1295
OomphInfo oomph_info
Definition: oomph_definitions.cc:319

References apply_plane_rotation(), beta, oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::IterativeLinearSolver::Doc_convergence_history, oomph::LinearSolver::Doc_time, boost::multiprecision::fabs(), generate_plane_rotation(), oomph::BlockPreconditioner< CRDoubleMatrix >::get_block_vector(), oomph::BlockPreconditioner< CRDoubleMatrix >::get_block_vectors(), H, i, oomph::Vector< _Tp >::initialise(), Iterations, k, Matrix_pt, oomph::IterativeLinearSolver::Max_iter, oomph::CRDoubleMatrix::multiply(), Navier_stokes_subsidiary_preconditioner_pt, oomph::BlockPreconditioner< CRDoubleMatrix >::nblock_types(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, oomph::IterativeLinearSolver::Output_file_stream, Preconditioner_LHS, oomph::SpaceTimeNavierStokesSubsidiaryPreconditioner::preconditioner_solve(), UniformPSDSelfTest::r, oomph::DoubleMatrixBase::residual(), oomph::BlockPreconditioner< CRDoubleMatrix >::return_block_vector(), s, BiharmonicTestFunctions1::solution(), oomph::IterativeLinearSolver::Solution_time, oomph::IterativeLinearSolver::Throw_error_after_max_iter, oomph::TimingHelpers::timer(), oomph::IterativeLinearSolver::Tolerance, update(), v, and w.

◆ preconditioner_solve() [2/2]

void oomph::GMRESBlockPreconditioner::preconditioner_solve ( const DoubleVector r,
DoubleVector z 
)
virtual

Apply preconditioner to r.

Implements oomph::Preconditioner.

◆ set_preconditioner_LHS() [1/2]

void oomph::GMRESBlockPreconditioner::set_preconditioner_LHS ( )
inline

Set left preconditioning (the default)

328  {
329  Preconditioner_LHS = true;
330  }

References Preconditioner_LHS.

◆ set_preconditioner_LHS() [2/2]

void oomph::GMRESBlockPreconditioner::set_preconditioner_LHS ( )
inline

Set left preconditioning (the default)

335  {
336  Preconditioner_LHS = true;
337  }

References Preconditioner_LHS.

◆ set_preconditioner_RHS() [1/2]

void oomph::GMRESBlockPreconditioner::set_preconditioner_RHS ( )
inline

Enable right preconditioning.

334  {
335  Preconditioner_LHS = false;
336  }

References Preconditioner_LHS.

◆ set_preconditioner_RHS() [2/2]

void oomph::GMRESBlockPreconditioner::set_preconditioner_RHS ( )
inline

Enable right preconditioning.

341  {
342  Preconditioner_LHS = false;
343  }

References Preconditioner_LHS.

◆ setup() [1/8]

void oomph::GMRESBlockPreconditioner::setup ( )
virtual

Setup the preconditioner.

Setup for the GMRES block preconditioner.

Implements oomph::Preconditioner.

576  {
577  // Clean up any previously created data
578  clean_up_memory();
579 
580  // If we're meant to build silently
581  if (this->Silent_preconditioner_setup == true)
582  {
583  // Store the output stream pointer
584  this->Stream_pt = oomph_info.stream_pt();
585 
586  // Now set the oomph_info stream pointer to the null stream to
587  // disable all possible output
589  }
590 
591  // Start the timer for the block setup
592  double t_block_setup_start = TimingHelpers::timer();
593 
594  // Set up block look up schemes (done automatically in the
595  // BlockPreconditioner base class, based on the information
596  // provided in the block-preconditionable elements in the problem)
597 
598  // This preconditioner has two types of block:
599  // Type 0: Velocity - Corresponding to DOF type 0 & 1
600  // Type 1: Pressure - Corresponding to DOF type 2
601  unsigned n_dof_types = 0;
602 
603  // If this has been set up as a subsidiary preconditioner
605  {
606  // Get the number of dof types (will be told by the master preconditioner)
607  n_dof_types = this->ndof_types();
608 
609  // Output the number of dof types
610  oomph_info << "Number of dof types: " << n_dof_types << std::endl;
611 
612  // Make sure there's only 3 dof types for now!
613  if (n_dof_types != 3)
614  {
615  // Allocate space for an error message
616  std::ostringstream error_message;
617 
618  // Create the error message
619  error_message << "Should only be 3 dof types! You have " << n_dof_types
620  << " dof types!" << std::endl;
621 
622  // Throw an error
623  throw OomphLibError(error_message.str(),
626  }
627  }
628  // If it's being used as a master preconditioner
629  else
630  {
631  // Throw an error
632  throw OomphLibError("Currently only used as a subsidiary preconditioner!",
635  } // if (this->is_subsidiary_block_preconditioner())
636 
637  // Aggregrate everything together since GMRES itself isn't going to take
638  // advantage of the block structure...
639  Vector<unsigned> dof_to_block_map(n_dof_types, 0);
640 
641  // Call the generic block setup function
642  this->block_setup(dof_to_block_map);
643 
644  // Stop the timer
645  double t_block_setup_finish = TimingHelpers::timer();
646 
647  // Calculate the time difference
648  double block_setup_time = t_block_setup_finish - t_block_setup_start;
649 
650  // Document the time taken
651  oomph_info << "Time for block_setup(...) [sec]: " << block_setup_time
652  << std::endl;
653 
654  // Get the number of block types
655  unsigned n_block_type = this->nblock_types();
656 
657  // How many block types are there? Should only be 2...
658  oomph_info << "Number of block types: " << n_block_type << std::endl;
659 
660  // Space for the concatenated block matrix
661  Matrix_pt = new CRDoubleMatrix;
662 
663  // Get the (one and only) block to be used by this block preconditioner
664  this->get_block(0, 0, *Matrix_pt);
665 
666  // Create a new instance of the NS subsidiary preconditioner
668  new SpaceTimeNavierStokesSubsidiaryPreconditioner;
669 
670  // Do we need to doc. the memory statistics?
672  {
673  // How many rows are there in this block?
674  unsigned n_row = Matrix_pt->nrow();
675 
676  // How many nonzeros are there in this block?
677  unsigned n_nnz = Matrix_pt->nnz();
678 
679  // Compute the memory usage. The only memory overhead here (for the
680  // setup phase) is storing the system matrix
681  Memory_usage_in_bytes = ((2 * ((n_row + 1) * sizeof(int))) +
682  (n_nnz * (sizeof(int) + sizeof(double))));
683 
684  // We might as well document the memory statistics of the Navier-Stokes
685  // subsidiary block preconditioner while we're at it...
687  }
688 
689  // Create a map to declare which of the 3 dof types in the GMRES
690  // subsidiary preconditioner correspond to the dof types in the NS
691  // subsidiary block preconditioner
692  Vector<unsigned> dof_map(n_dof_types);
693 
694  // Loop over the dof types associated with the GMRES subsidiary block
695  // preconditioner
696  for (unsigned i = 0; i < n_dof_types; i++)
697  {
698  // There is, essentially, an identity mapping between the GMRES subsidiary
699  // block preconditioner and the NSSP w.r.t. the dof types
700  dof_map[i] = i;
701  }
702 
703  // Now turn it into an "proper" subsidiary preconditioner
706 
707  // Setup: The NS subsidiary preconditioner is itself a block preconditioner
708  // so we need to pass it a pointer to full-size matrix!
710 
711  // Remember that the preconditioner has been setup so the stored
712  // information can be wiped when we come here next...
714 
715  // If we're meant to build silently, reassign the oomph stream pointer
716  if (this->Silent_preconditioner_setup == true)
717  {
718  // Store the output stream pointer
719  oomph_info.stream_pt() = this->Stream_pt;
720 
721  // Reset our own stream pointer
722  this->Stream_pt = 0;
723  }
724  } // End of setup
void get_block(const unsigned &i, const unsigned &j, CRDoubleMatrix &output_matrix, const bool &ignore_replacement_block=false) const
Definition: block_preconditioner.h:673
CRDoubleMatrix * matrix_pt() const
Definition: block_preconditioner.h:520
bool is_subsidiary_block_preconditioner() const
Definition: block_preconditioner.h:2061
unsigned ndof_types() const
Return the total number of DOF types.
Definition: block_preconditioner.h:1694
void turn_into_subsidiary_block_preconditioner(BlockPreconditioner< MATRIX > *master_block_prec_pt, const Vector< unsigned > &doftype_in_master_preconditioner_coarse)
Definition: block_preconditioner.cc:2376
virtual void block_setup()
Definition: block_preconditioner.cc:2483
unsigned long nnz() const
Return the number of nonzero entries (the local nnz)
Definition: matrices.h:1096
unsigned long nrow() const
Return the number of rows of the matrix.
Definition: matrices.h:1002
std::ostream *& stream_pt()
Access function for the stream pointer.
Definition: oomph_definitions.h:464
std::ostream * Stream_pt
Pointer to the output stream – defaults to std::cout.
Definition: preconditioner.h:232
bool Silent_preconditioner_setup
Boolean to indicate whether or not the build should be done silently.
Definition: preconditioner.h:229
void setup()
Setup the preconditioner.
Definition: general_purpose_space_time_subsidiary_block_preconditioner.cc:61
void enable_doc_memory_usage()
Document the memory usage.
Definition: general_purpose_space_time_subsidiary_block_preconditioner.h:139
return int(ret)+1
Nullstream oomph_nullstream
Single (global) instantiation of the Nullstream.
Definition: oomph_definitions.cc:313

References oomph::BlockPreconditioner< CRDoubleMatrix >::block_setup(), clean_up_memory(), Compute_memory_statistics, oomph::SpaceTimeNavierStokesSubsidiaryPreconditioner::enable_doc_memory_usage(), oomph::BlockPreconditioner< CRDoubleMatrix >::get_block(), i, int(), oomph::BlockPreconditioner< CRDoubleMatrix >::is_subsidiary_block_preconditioner(), oomph::BlockPreconditioner< CRDoubleMatrix >::matrix_pt(), Matrix_pt, Memory_usage_in_bytes, Navier_stokes_subsidiary_preconditioner_pt, oomph::BlockPreconditioner< CRDoubleMatrix >::nblock_types(), oomph::BlockPreconditioner< CRDoubleMatrix >::ndof_types(), oomph::CRDoubleMatrix::nnz(), oomph::CRDoubleMatrix::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, oomph::oomph_nullstream, Preconditioner_has_been_setup, oomph::SpaceTimeNavierStokesSubsidiaryPreconditioner::setup(), oomph::Preconditioner::Silent_preconditioner_setup, oomph::OomphInfo::stream_pt(), oomph::Preconditioner::Stream_pt, oomph::TimingHelpers::timer(), and oomph::BlockPreconditioner< MATRIX >::turn_into_subsidiary_block_preconditioner().

◆ setup() [2/8]

void oomph::GMRESBlockPreconditioner::setup ( )
virtual

Setup the preconditioner.

Implements oomph::Preconditioner.

◆ setup() [3/8]

virtual void oomph::Preconditioner::setup
virtual

For some reason we need to remind the compiler that there is also a function named setup in the base class.

Implements oomph::Preconditioner.

◆ setup() [4/8]

virtual void oomph::Preconditioner::setup
virtual

For some reason we need to remind the compiler that there is also a function named setup in the base class.

Implements oomph::Preconditioner.

◆ setup() [5/8]

void oomph::Preconditioner::setup
inlinevirtual

For some reason we need to remind the compiler that there is also a function named setup in the base class.

Implements oomph::Preconditioner.

121  {
123  setup(matrix_pt);
124  }
void setup()
Setup the preconditioner.
Definition: general_purpose_space_time_subsidiary_block_preconditioner.cc:575
void obsolete()
Output warning message.
Definition: oomph_utilities.cc:1102

◆ setup() [6/8]

void oomph::Preconditioner::setup
inlinevirtual

For some reason we need to remind the compiler that there is also a function named setup in the base class.

Implements oomph::Preconditioner.

121  {
123  setup(matrix_pt);
124  }

◆ setup() [7/8]

void oomph::Preconditioner::setup
inlinevirtual

For some reason we need to remind the compiler that there is also a function named setup in the base class.

Implements oomph::Preconditioner.

95  {
96  // Store matrix pointer
98 
99  // Extract and store communicator pointer
100  DistributableLinearAlgebraObject* dist_obj_pt =
102  if (dist_obj_pt != 0)
103  {
104  set_comm_pt(dist_obj_pt->distribution_pt()->communicator_pt());
105  }
106  else
107  {
108  set_comm_pt(0);
109  }
110 
111  double setup_time_start = TimingHelpers::timer();
112  setup();
113  double setup_time_finish = TimingHelpers::timer();
114  Setup_time = setup_time_finish - setup_time_start;
115  }
DistributableLinearAlgebraObject()
Default constructor - create a distribution.
Definition: linear_algebra_distribution.h:438
double Setup_time
The time it takes to set up this preconditioner.
Definition: preconditioner.h:243
virtual void set_comm_pt(const OomphCommunicator *const comm_pt)
Set the communicator pointer.
Definition: preconditioner.h:193
virtual void set_matrix_pt(DoubleMatrixBase *matrix_pt)
Set the matrix pointer.
Definition: preconditioner.h:165

◆ setup() [8/8]

void oomph::Preconditioner::setup
inlinevirtual

For some reason we need to remind the compiler that there is also a function named setup in the base class.

Implements oomph::Preconditioner.

95  {
96  // Store matrix pointer
98 
99  // Extract and store communicator pointer
100  DistributableLinearAlgebraObject* dist_obj_pt =
102  if (dist_obj_pt != 0)
103  {
104  set_comm_pt(dist_obj_pt->distribution_pt()->communicator_pt());
105  }
106  else
107  {
108  set_comm_pt(0);
109  }
110 
111  double setup_time_start = TimingHelpers::timer();
112  setup();
113  double setup_time_finish = TimingHelpers::timer();
114  Setup_time = setup_time_finish - setup_time_start;
115  }

◆ solve() [1/2]

void oomph::GMRESBlockPreconditioner::solve ( Problem *const &  problem_pt,
DoubleVector result 
)
inlinevirtual

Solver: Takes pointer to problem and returns the results vector which contains the solution of the linear system defined by the problem's fully assembled Jacobian and residual vector.

Implements oomph::LinearSolver.

312  {
313  // Broken
314  throw OomphLibError("Can't use this interface!",
317  } // End of solve

References OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ solve() [2/2]

void oomph::GMRESBlockPreconditioner::solve ( Problem *const &  problem_pt,
DoubleVector result 
)
inlinevirtual

Solver: Takes pointer to problem and returns the results vector which contains the solution of the linear system defined by the problem's fully assembled Jacobian and residual vector.

Implements oomph::LinearSolver.

319  {
320  // Broken
321  throw OomphLibError("Can't use this interface!",
324  } // End of solve

References OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ update() [1/2]

void oomph::GMRESBlockPreconditioner::update ( const unsigned k,
const Vector< Vector< double >> &  H,
const Vector< double > &  s,
const Vector< DoubleVector > &  v,
const DoubleVector block_x_with_size_of_full_x,
DoubleVector x 
)
inlineprivate

Helper function to update the result vector using the result, x=x_0+V_m*y

426  {
427  // Make a local copy of s
428  Vector<double> y(s);
429 
430  // Backsolve:
431  for (int i = int(k); i >= 0; i--)
432  {
433  // Divide the i-th entry of y by the i-th diagonal entry of H
434  y[i] /= H[i][i];
435 
436  // Loop over the previous values of y and update
437  for (int j = i - 1; j >= 0; j--)
438  {
439  // Update the j-th entry of y
440  y[j] -= H[i][j] * y[i];
441  }
442  } // for (int i=int(k);i>=0;i--)
443 
444  // Store the number of rows in the result vector
445  unsigned n_x = x.nrow();
446 
447  // Build a temporary vector with entries initialised to 0.0
448  DoubleVector temp(x.distribution_pt(), 0.0);
449 
450  // Build a temporary vector with entries initialised to 0.0
451  DoubleVector z(x.distribution_pt(), 0.0);
452 
453  // Get access to the underlying values
454  double* temp_pt = temp.values_pt();
455 
456  // Calculate x=Vy
457  for (unsigned j = 0; j <= k; j++)
458  {
459  // Get access to j-th column of v
460  const double* vj_pt = v[j].values_pt();
461 
462  // Loop over the entries of the vector, temp
463  for (unsigned i = 0; i < n_x; i++)
464  {
465  temp_pt[i] += vj_pt[i] * y[j];
466  }
467  } // for (unsigned j=0;j<=k;j++)
468 
469  // If we're using LHS preconditioning
470  if (Preconditioner_LHS)
471  {
472  // Since we're using LHS preconditioning the preconditioner is applied
473  // to the matrix and RHS vector so we simply update the value of x
474  x += temp;
475  }
476  // If we're using RHS preconditioning
477  else
478  {
479  // This is pretty inefficient but there is no other way to do this with
480  // block sub preconditioners as far as I can tell because they demand
481  // to have the full r and z vectors...
482  DoubleVector block_z_with_size_of_full_z(
483  block_x_with_size_of_full_x.distribution_pt());
484  DoubleVector temp_with_size_of_full_rhs(
485  block_x_with_size_of_full_x.distribution_pt());
486 
487  // Reorder the entries of temp and put them into the global-sized vector
488  this->return_block_vector(0, temp, temp_with_size_of_full_rhs);
489 
490  // Solve on the global-sized vectors
492  temp_with_size_of_full_rhs, block_z_with_size_of_full_z);
493 
494  // Now reorder the entries and put them into z
495  this->get_block_vector(0, block_z_with_size_of_full_z, z);
496 
497  // Since we're using RHS preconditioning the preconditioner is applied
498  // to the solution vector
499  // preconditioner_pt()->preconditioner_solve(temp,z);
500 
501  // Use the update: x_m=x_0+inv(M)Vy [see Saad Y,"Iterative methods for
502  // sparse linear systems", p.284]
503  x += z;
504  }
505  } // End of update
Scalar * y
Definition: level1_cplx_impl.h:128
list x
Definition: plotDoE.py:28
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::BlockPreconditioner< CRDoubleMatrix >::get_block_vector(), H, i, j, k, Navier_stokes_subsidiary_preconditioner_pt, Preconditioner_LHS, oomph::SpaceTimeNavierStokesSubsidiaryPreconditioner::preconditioner_solve(), oomph::BlockPreconditioner< CRDoubleMatrix >::return_block_vector(), s, v, oomph::DoubleVector::values_pt(), plotDoE::x, and y.

Referenced by preconditioner_solve(), and smc.smc::recursiveBayesian().

◆ update() [2/2]

void oomph::GMRESBlockPreconditioner::update ( const unsigned k,
const Vector< Vector< double >> &  H,
const Vector< double > &  s,
const Vector< DoubleVector > &  v,
const DoubleVector block_x_with_size_of_full_x,
DoubleVector x 
)
inlineprivate

Helper function to update the result vector using the result, x=x_0+V_m*y

433  {
434  // Make a local copy of s
435  Vector<double> y(s);
436 
437  // Backsolve:
438  for (int i = int(k); i >= 0; i--)
439  {
440  // Divide the i-th entry of y by the i-th diagonal entry of H
441  y[i] /= H[i][i];
442 
443  // Loop over the previous values of y and update
444  for (int j = i - 1; j >= 0; j--)
445  {
446  // Update the j-th entry of y
447  y[j] -= H[i][j] * y[i];
448  }
449  } // for (int i=int(k);i>=0;i--)
450 
451  // Store the number of rows in the result vector
452  unsigned n_x = x.nrow();
453 
454  // Build a temporary vector with entries initialised to 0.0
455  DoubleVector temp(x.distribution_pt(), 0.0);
456 
457  // Build a temporary vector with entries initialised to 0.0
458  DoubleVector z(x.distribution_pt(), 0.0);
459 
460  // Get access to the underlying values
461  double* temp_pt = temp.values_pt();
462 
463  // Calculate x=Vy
464  for (unsigned j = 0; j <= k; j++)
465  {
466  // Get access to j-th column of v
467  const double* vj_pt = v[j].values_pt();
468 
469  // Loop over the entries of the vector, temp
470  for (unsigned i = 0; i < n_x; i++)
471  {
472  temp_pt[i] += vj_pt[i] * y[j];
473  }
474  } // for (unsigned j=0;j<=k;j++)
475 
476  // If we're using LHS preconditioning
477  if (Preconditioner_LHS)
478  {
479  // Since we're using LHS preconditioning the preconditioner is applied
480  // to the matrix and RHS vector so we simply update the value of x
481  x += temp;
482  }
483  // If we're using RHS preconditioning
484  else
485  {
486  // This is pretty inefficient but there is no other way to do this with
487  // block sub preconditioners as far as I can tell because they demand
488  // to have the full r and z vectors...
489  DoubleVector block_z_with_size_of_full_z(
490  block_x_with_size_of_full_x.distribution_pt());
491  DoubleVector temp_with_size_of_full_rhs(
492  block_x_with_size_of_full_x.distribution_pt());
493 
494  // Reorder the entries of temp and put them into the global-sized vector
495  this->return_block_vector(0, temp, temp_with_size_of_full_rhs);
496 
497  // Solve on the global-sized vectors
499  temp_with_size_of_full_rhs, block_z_with_size_of_full_z);
500 
501  // Now reorder the entries and put them into z
502  this->get_block_vector(0, block_z_with_size_of_full_z, z);
503 
504  // Since we're using RHS preconditioning the preconditioner is applied
505  // to the solution vector
506  // preconditioner_pt()->preconditioner_solve(temp,z);
507 
508  // Use the update: x_m=x_0+inv(M)Vy [see Saad Y,"Iterative methods for
509  // sparse linear systems", p.284]
510  x += z;
511  }
512  } // End of update

References oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::BlockPreconditioner< CRDoubleMatrix >::get_block_vector(), H, i, j, k, Navier_stokes_subsidiary_preconditioner_pt, Preconditioner_LHS, oomph::SpaceTimeNavierStokesSubsidiaryPreconditioner::preconditioner_solve(), oomph::BlockPreconditioner< CRDoubleMatrix >::return_block_vector(), s, v, oomph::DoubleVector::values_pt(), plotDoE::x, and y.

Referenced by smc.smc::recursiveBayesian().

Member Data Documentation

◆ Compute_memory_statistics

bool oomph::GMRESBlockPreconditioner::Compute_memory_statistics
private

Flag to indicate whether or not to record the memory statistics this preconditioner

Referenced by disable_doc_memory_statistics(), disable_doc_memory_usage(), enable_doc_memory_statistics(), enable_doc_memory_usage(), get_memory_usage_in_bytes(), GMRESBlockPreconditioner(), and setup().

◆ Iterations

unsigned oomph::GMRESBlockPreconditioner::Iterations
private

Number of iterations taken.

Referenced by iterations(), and preconditioner_solve().

◆ Matrix_pt

CRDoubleMatrix * oomph::GMRESBlockPreconditioner::Matrix_pt
private

Pointer to matrix.

Referenced by clean_up_memory(), preconditioner_solve(), and setup().

◆ Memory_usage_in_bytes

double oomph::GMRESBlockPreconditioner::Memory_usage_in_bytes
private

Storage for the memory usage of the solver if the flag above is set to true (in bytes)

Referenced by get_memory_usage_in_bytes(), GMRESBlockPreconditioner(), and setup().

◆ Navier_stokes_subsidiary_preconditioner_pt

SpaceTimeNavierStokesSubsidiaryPreconditioner * oomph::GMRESBlockPreconditioner::Navier_stokes_subsidiary_preconditioner_pt
private

Pointer to the preconditioner for the block matrix.

Referenced by clean_up_memory(), navier_stokes_subsidiary_preconditioner_pt(), preconditioner_solve(), setup(), and update().

◆ Preconditioner_has_been_setup

bool oomph::GMRESBlockPreconditioner::Preconditioner_has_been_setup
private

Control flag is true if the preconditioner has been setup (used so we can wipe the data when the preconditioner is called again)

Referenced by clean_up_memory(), get_memory_usage_in_bytes(), and setup().

◆ Preconditioner_LHS

bool oomph::GMRESBlockPreconditioner::Preconditioner_LHS
private

boolean indicating use of left hand preconditioning (if true) or right hand preconditioning (if false)

Referenced by preconditioner_solve(), set_preconditioner_LHS(), set_preconditioner_RHS(), and update().


The documentation for this class was generated from the following files: