oomph::CG< MATRIX > Class Template Reference

The conjugate gradient method. More...

#include <iterative_linear_solver.h>

+ Inheritance diagram for oomph::CG< MATRIX >:

Public Member Functions

 CG ()
 Constructor. More...
 
virtual ~CG ()
 Destructor (cleanup storage) More...
 
 CG (const CG &)=delete
 Broken copy constructor. More...
 
void operator= (const CG &)=delete
 Broken assignment operator. More...
 
void disable_resolve ()
 Overload disable resolve so that it cleans up memory too. More...
 
void solve (Problem *const &problem_pt, DoubleVector &result)
 
void solve (DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &solution)
 
void resolve (const DoubleVector &rhs, DoubleVector &result)
 
unsigned iterations () const
 Number of iterations taken. More...
 
- 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 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_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)
 

Private Member Functions

void solve_helper (DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &solution)
 General interface to solve function. More...
 
void clean_up_memory ()
 Cleanup data that's stored for resolve (if any has been stored) More...
 

Private Attributes

unsigned Iterations
 Number of iterations taken. More...
 
MATRIX * Matrix_pt
 Pointer to matrix. More...
 
bool Resolving
 
bool Matrix_can_be_deleted
 

Additional Inherited Members

- Protected Member Functions inherited from oomph::DistributableLinearAlgebraObject
void clear_distribution ()
 
- 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
 
- Static Protected Attributes inherited from oomph::IterativeLinearSolver
static IdentityPreconditioner Default_preconditioner
 

Detailed Description

template<typename MATRIX>
class oomph::CG< MATRIX >

The conjugate gradient method.

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

Constructor & Destructor Documentation

◆ CG() [1/2]

template<typename MATRIX >
oomph::CG< MATRIX >::CG ( )
inline

Constructor.

288  : Iterations(0),
289  Matrix_pt(0),
290  Resolving(false),
292  {
293  }
unsigned Iterations
Number of iterations taken.
Definition: iterative_linear_solver.h:385
MATRIX * Matrix_pt
Pointer to matrix.
Definition: iterative_linear_solver.h:388
bool Matrix_can_be_deleted
Definition: iterative_linear_solver.h:396
bool Resolving
Definition: iterative_linear_solver.h:392

◆ ~CG()

template<typename MATRIX >
virtual oomph::CG< MATRIX >::~CG ( )
inlinevirtual

Destructor (cleanup storage)

298  {
299  clean_up_memory();
300  }
void clean_up_memory()
Cleanup data that's stored for resolve (if any has been stored)
Definition: iterative_linear_solver.h:375

References oomph::CG< MATRIX >::clean_up_memory().

◆ CG() [2/2]

template<typename MATRIX >
oomph::CG< MATRIX >::CG ( const CG< MATRIX > &  )
delete

Broken copy constructor.

Member Function Documentation

◆ clean_up_memory()

template<typename MATRIX >
void oomph::CG< MATRIX >::clean_up_memory ( )
inlineprivatevirtual

Cleanup data that's stored for resolve (if any has been stored)

Reimplemented from oomph::LinearSolver.

376  {
377  if ((Matrix_pt != 0) && (Matrix_can_be_deleted))
378  {
379  delete Matrix_pt;
380  Matrix_pt = 0;
381  }
382  }

References oomph::CG< MATRIX >::Matrix_can_be_deleted, and oomph::CG< MATRIX >::Matrix_pt.

Referenced by oomph::CG< MATRIX >::disable_resolve(), and oomph::CG< MATRIX >::~CG().

◆ disable_resolve()

template<typename MATRIX >
void oomph::CG< MATRIX >::disable_resolve ( )
inlinevirtual

Overload disable resolve so that it cleans up memory too.

Reimplemented from oomph::LinearSolver.

310  {
312  clean_up_memory();
313  }
virtual void disable_resolve()
Definition: linear_solver.h:144

References oomph::CG< MATRIX >::clean_up_memory(), and oomph::LinearSolver::disable_resolve().

◆ iterations()

template<typename MATRIX >
unsigned oomph::CG< MATRIX >::iterations ( ) const
inlinevirtual

Number of iterations taken.

Implements oomph::IterativeLinearSolver.

362  {
363  return Iterations;
364  }

References oomph::CG< MATRIX >::Iterations.

◆ operator=()

template<typename MATRIX >
void oomph::CG< MATRIX >::operator= ( const CG< MATRIX > &  )
delete

Broken assignment operator.

◆ resolve()

template<typename MATRIX >
void CG< MATRIX >::resolve ( const DoubleVector rhs,
DoubleVector result 
)
virtual

Re-solve the system defined by the last assembled Jacobian and the rhs vector specified here. Solution is returned in the vector result.

Reimplemented from oomph::LinearSolver.

923  {
924  // We are re-solving
925  Resolving = true;
926 
927 #ifdef PARANOID
928  if (Matrix_pt == 0)
929  {
930  throw OomphLibError("No matrix was stored -- cannot re-solve",
933  }
934 #endif
935 
936  // Call linear algebra-style solver
937  this->solve(Matrix_pt, rhs, result);
938 
939  // Reset re-solving flag
940  Resolving = false;
941  }
void solve(Problem *const &problem_pt, DoubleVector &result)
Definition: iterative_linear_solver.cc:950
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and solve.

◆ solve() [1/2]

template<typename MATRIX >
void oomph::CG< MATRIX >::solve ( DoubleMatrixBase *const &  matrix_pt,
const DoubleVector rhs,
DoubleVector solution 
)
inlinevirtual

Linear-algebra-type solver: Takes pointer to a matrix and rhs vector and returns the solution of the linear system.

Reimplemented from oomph::LinearSolver.

326  {
327  // Store the matrix if required
328  if ((Enable_resolve) && (!Resolving))
329  {
330  Matrix_pt = dynamic_cast<MATRIX*>(matrix_pt);
331 
332  // Matrix has been passed in from the outside so we must not
333  // delete it
334  Matrix_can_be_deleted = false;
335  }
336 
337  // set the distribution
338  if (dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt))
339  {
340  // the solver has the same distribution as the matrix if possible
341  this->build_distribution(
342  dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt)
343  ->distribution_pt());
344  }
345  else
346  {
347  // the solver has the same distribution as the RHS
348  this->build_distribution(rhs.distribution_pt());
349  }
350 
351  // Call the helper function
352  this->solve_helper(matrix_pt, rhs, solution);
353  }
void solve_helper(DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &solution)
General interface to solve function.
Definition: iterative_linear_solver.cc:605
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
Definition: linear_algebra_distribution.h:457
void build_distribution(const LinearAlgebraDistribution *const dist_pt)
Definition: linear_algebra_distribution.h:507
DistributableLinearAlgebraObject()
Default constructor - create a distribution.
Definition: linear_algebra_distribution.h:438
bool Enable_resolve
Definition: linear_solver.h:73
void solution(const Vector< double > &x, Vector< double > &u)
Definition: two_d_biharmonic.cc:113

References oomph::DistributableLinearAlgebraObject::build_distribution(), oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::LinearSolver::Enable_resolve, oomph::CG< MATRIX >::Matrix_can_be_deleted, oomph::CG< MATRIX >::Matrix_pt, oomph::CG< MATRIX >::Resolving, BiharmonicTestFunctions1::solution(), and oomph::CG< MATRIX >::solve_helper().

◆ solve() [2/2]

template<typename MATRIX >
void CG< MATRIX >::solve ( Problem *const &  problem_pt,
DoubleVector result 
)
virtual

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.

951  {
952  // Initialise timer
953  double t_start = TimingHelpers::timer();
954 
955  // We're not re-solving
956  Resolving = false;
957 
958  // Get rid of any previously stored data
959  clean_up_memory();
960 
961  // Get Jacobian matrix in format specified by template parameter
962  // and nonlinear residual vector
963  Matrix_pt = new MATRIX;
964  DoubleVector f;
965  problem_pt->get_jacobian(f, *Matrix_pt);
966 
967  // We've made the matrix, we can delete it...
968  Matrix_can_be_deleted = true;
969 
970  // Doc time for setup
971  double t_end = TimingHelpers::timer();
972  Jacobian_setup_time = t_end - t_start;
973 
974  if (Doc_time)
975  {
976  oomph_info << "Time for setup of Jacobian [sec]: " << Jacobian_setup_time
977  << std::endl;
978  }
979 
980  // set the distribution
981  if (dynamic_cast<DistributableLinearAlgebraObject*>(Matrix_pt))
982  {
983  // the solver has the same distribution as the matrix if possible
984  this->build_distribution(
986  ->distribution_pt());
987  }
988  else
989  {
990  // the solver has the same distribution as the RHS
991  this->build_distribution(f.distribution_pt());
992  }
993 
994  // if the result vector is not setup
995  if (!result.distribution_pt()->built())
996  {
997  result.build(this->distribution_pt(), 0.0);
998  }
999 
1000  // Call linear algebra-style solver
1001  if (!(*result.distribution_pt() == *this->distribution_pt()))
1002  {
1003  LinearAlgebraDistribution temp_global_dist(result.distribution_pt());
1004  result.build(this->distribution_pt(), 0.0);
1005  this->solve_helper(Matrix_pt, f, result);
1006  result.redistribute(&temp_global_dist);
1007  }
1008  else
1009  {
1010  this->solve_helper(Matrix_pt, f, result);
1011  }
1012 
1013  // Kill matrix unless it's still required for resolve
1015  };
std::vector< double > DoubleVector
loads clump configuration
Definition: ClumpInput.h:26
double Jacobian_setup_time
Jacobian setup time.
Definition: iterative_linear_solver.h:248
bool Doc_time
Boolean flag that indicates whether the time taken.
Definition: linear_solver.h:77
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
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 oomph::DoubleVector::build(), oomph::LinearAlgebraDistribution::built(), oomph::TerminateHelper::clean_up_memory(), oomph::DistributableLinearAlgebraObject::distribution_pt(), f(), oomph::Problem::get_jacobian(), oomph::oomph_info, oomph::DoubleVector::redistribute(), and oomph::TimingHelpers::timer().

◆ solve_helper()

template<typename MATRIX >
void CG< MATRIX >::solve_helper ( DoubleMatrixBase *const &  matrix_pt,
const DoubleVector rhs,
DoubleVector solution 
)
private

General interface to solve function.

/////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// Linear-algebra-type solver: Takes pointer to a matrix and rhs vector and returns the solution of the linear system. Algorithm and variable names based on "Matrix Computations, 2nd Ed." Golub & van Loan, John Hopkins University Press(1989), page 529.

608  {
609 #ifdef PARANOID
610  // check that the rhs vector is setup
611  if (!rhs.built())
612  {
613  std::ostringstream error_message_stream;
614  error_message_stream << "The vectors rhs must be setup";
615  throw OomphLibError(error_message_stream.str(),
618  }
619 
620  // check that the matrix is square
621  if (matrix_pt->nrow() != matrix_pt->ncol())
622  {
623  std::ostringstream error_message_stream;
624  error_message_stream << "The matrix at matrix_pt must be square.";
625  throw OomphLibError(error_message_stream.str(),
628  }
629 
630  // check that the matrix and the rhs vector have the same nrow()
631  if (matrix_pt->nrow() != rhs.nrow())
632  {
633  std::ostringstream error_message_stream;
634  error_message_stream
635  << "The matrix and the rhs vector must have the same number of rows.";
636  throw OomphLibError(error_message_stream.str(),
639  }
640 
641  // if the matrix is distributable then it too should have the same
642  // communicator as the rhs vector
643  DistributableLinearAlgebraObject* dist_matrix_pt =
644  dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt);
645  if (dist_matrix_pt != 0)
646  {
647  if (!(*dist_matrix_pt->distribution_pt() == *rhs.distribution_pt()))
648  {
649  std::ostringstream error_message_stream;
650  error_message_stream
651  << "The matrix matrix_pt must have the same communicator as the "
652  "vectors"
653  << " rhs and result must have the same communicator";
654  throw OomphLibError(error_message_stream.str(),
657  }
658  }
659  // if the matrix is not distributable then it the rhs vector should not be
660  // distributed
661  else
662  {
663  if (rhs.distribution_pt()->distributed())
664  {
665  std::ostringstream error_message_stream;
666  error_message_stream
667  << "The matrix (matrix_pt) is not distributable and therefore the rhs"
668  << " vector must not be distributed";
669  throw OomphLibError(error_message_stream.str(),
672  }
673  }
674  // if the result vector is setup then check it has the same distribution
675  // as the rhs
676  if (solution.built())
677  {
678  if (!(*solution.distribution_pt() == *rhs.distribution_pt()))
679  {
680  std::ostringstream error_message_stream;
681  error_message_stream << "The solution vector distribution has been "
682  "setup; it must have the "
683  << "same distribution as the rhs vector.";
684  throw OomphLibError(error_message_stream.str(),
687  }
688  }
689 #endif
690 
691  // setup the solution if it is not
692  if (!solution.distribution_pt()->built())
693  {
694  solution.build(this->distribution_pt(), 0.0);
695  }
696  // zero
697  else
698  {
699  solution.initialise(0.0);
700  }
701 
702  // Get number of dofs
703  // unsigned n_dof=rhs.size();
704  unsigned nrow_local = this->nrow_local();
705 
706  // Initialise counter
707  unsigned counter = 0;
708 
709  // Time solver
710  double t_start = TimingHelpers::timer();
711 
712  // Initialise: Zero initial guess so the initial residual is
713  // equal to the RHS
714  DoubleVector x(this->distribution_pt(), 0.0);
715  DoubleVector residual(rhs);
716  double residual_norm = residual.norm();
717  double rhs_norm = residual_norm;
718  if (rhs_norm == 0.0) rhs_norm = 1.0;
719 
720  // Normalised residual
721  double normalised_residual_norm = residual_norm / rhs_norm;
722 
723  // if required will document convergence history to screen or file (if
724  // stream open)
726  {
727  if (!Output_file_stream.is_open())
728  {
729  oomph_info << 0 << " " << normalised_residual_norm << std::endl;
730  }
731  else
732  {
733  Output_file_stream << 0 << " " << normalised_residual_norm << std::endl;
734  }
735  }
736 
737  // Check immediate convergence
738  if (normalised_residual_norm < Tolerance)
739  {
740  if (Doc_time)
741  {
742  oomph_info << "CG converged immediately" << std::endl;
743  }
744  solution = x;
745 
746  // Doc time for solver
747  double t_end = TimingHelpers::timer();
748  Solution_time = t_end - t_start;
749 
750  if (Doc_time)
751  {
752  oomph_info << "Time for solve with CG [sec]: " << Solution_time
753  << std::endl;
754  }
755  return;
756  }
757 
758 
759  // Setup preconditioner only if we're not re-solving
760  if (!Resolving)
761  {
762  // only setup the preconditioner if required
764  {
765  // Setup preconditioner from the Jacobian matrix
766  double t_start_prec = TimingHelpers::timer();
767 
768  preconditioner_pt()->setup(matrix_pt);
769 
770  // Doc time for setup of preconditioner
771  double t_end_prec = TimingHelpers::timer();
772  Preconditioner_setup_time = t_end_prec - t_start_prec;
773 
774  if (Doc_time)
775  {
776  oomph_info << "Time for setup of preconditioner [sec]: "
777  << Preconditioner_setup_time << std::endl;
778  }
779  }
780  }
781  else
782  {
783  if (Doc_time)
784  {
785  oomph_info << "Setup of preconditioner is bypassed in resolve mode"
786  << std::endl;
787  }
788  }
789 
790 
791  // Auxiliary vectors
792  // Vector<double> z(n_dof),p(n_dof),jacobian_times_p(n_dof,0.0);
793  DoubleVector z(this->distribution_pt(), 0.0),
794  p(this->distribution_pt(), 0.0),
795  jacobian_times_p(this->distribution_pt(), 0.0);
796 
797  // Auxiliary values
798  double alpha, beta, rz;
799  double prev_rz = 0.0;
800 
801  // Main iteration
802  while ((normalised_residual_norm > Tolerance) && (counter != Max_iter))
803  {
804  // Apply precondtitioner: z=P^-1*r
805  preconditioner_pt()->preconditioner_solve(residual, z);
806 
807  // P vector is computed differently for first and subsequent steps
808  if (counter == 0)
809  {
810  p = z;
811  rz = residual.dot(z);
812  }
813  // Subsequent steps
814  else
815  {
816  rz = residual.dot(z);
817  beta = rz / prev_rz;
818  for (unsigned i = 0; i < nrow_local; i++)
819  {
820  p[i] = z[i] + beta * p[i];
821  }
822  }
823 
824 
825  // Matrix vector product
826  matrix_pt->multiply(p, jacobian_times_p);
827  double pq = p.dot(jacobian_times_p);
828  alpha = rz / pq;
829 
830  // Update
831  prev_rz = rz;
832  for (unsigned i = 0; i < nrow_local; i++)
833  {
834  x[i] += alpha * p[i];
835  residual[i] -= alpha * jacobian_times_p[i];
836  }
837 
838 
839  // Calculate the 2norm
840  residual_norm = residual.norm();
841 
842  // Difference between the initial and current 2norm residual
843  normalised_residual_norm = residual_norm / rhs_norm;
844 
845 
846  // if required will document convergence history to screen or file (if
847  // stream open)
849  {
850  if (!Output_file_stream.is_open())
851  {
852  oomph_info << counter << " " << normalised_residual_norm << std::endl;
853  }
854  else
855  {
856  Output_file_stream << counter << " " << normalised_residual_norm
857  << std::endl;
858  }
859  }
860 
861  counter = counter + 1;
862 
863  } // end while
864 
865 
866  if (counter >= Max_iter)
867  {
868  oomph_info << std::endl;
869  oomph_info << "CG did not converge to required tolerance! " << std::endl;
870  oomph_info << "Returning with normalised residual norm: "
871  << normalised_residual_norm << std::endl;
872  oomph_info << "after " << counter << " iterations." << std::endl;
873  oomph_info << std::endl;
874  }
875  else
876  {
877  if (Doc_time)
878  {
879  oomph_info << std::endl;
880  oomph_info << "CG converged. Normalised residual norm: "
881  << normalised_residual_norm << std::endl;
882  oomph_info << "Number of iterations to convergence: " << counter
883  << std::endl;
884  oomph_info << std::endl;
885  }
886  }
887 
888 
889  // Store number if iterations taken
890  Iterations = counter;
891 
892  // Copy result back
893  solution = x;
894 
895  // Doc time for solver
896  double t_end = TimingHelpers::timer();
897  Solution_time = t_end - t_start;
898 
899  if (Doc_time)
900  {
901  oomph_info << "Time for solve with CG [sec]: " << Solution_time
902  << std::endl;
903  }
904 
905  if ((counter >= Max_iter) && (Throw_error_after_max_iter))
906  {
907  std::string err = "Solver failed to converge and you requested an error";
908  err += " on convergence failures.";
909  throw OomphLibError(
911  }
912 
913  } // end CG
int i
Definition: BiCGSTAB_step_by_step.cpp:9
float * p
Definition: Tutorial_Map_using.cpp:9
unsigned nrow_local() const
access function for the num of local rows on this processor.
Definition: linear_algebra_distribution.h:469
double Tolerance
Convergence tolerance.
Definition: iterative_linear_solver.h:239
bool Throw_error_after_max_iter
Definition: iterative_linear_solver.h:262
Preconditioner *& preconditioner_pt()
Access function to preconditioner.
Definition: iterative_linear_solver.h:95
double Preconditioner_setup_time
Preconditioner setup time.
Definition: iterative_linear_solver.h:254
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 Setup_preconditioner_before_solve
Definition: iterative_linear_solver.h:258
void setup(DoubleMatrixBase *matrix_pt)
Definition: preconditioner.h:94
virtual void preconditioner_solve(const DoubleVector &r, DoubleVector &z)=0
RealScalar alpha
Definition: level1_cplx_impl.h:151
Scalar beta
Definition: level2_cplx_impl.h:36
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
list x
Definition: plotDoE.py:28

References alpha, beta, oomph::DoubleVector::built(), oomph::LinearAlgebraDistribution::distributed(), oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::DoubleVector::dot(), i, Global_Variables::Iterations, oomph::BlackBoxFDNewtonSolver::Max_iter, oomph::DoubleMatrixBase::multiply(), oomph::DoubleMatrixBase::ncol(), oomph::DoubleVector::norm(), oomph::DistributableLinearAlgebraObject::nrow(), oomph::DoubleMatrixBase::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, p, BiharmonicTestFunctions1::solution(), oomph::Global_string_for_annotation::string(), oomph::TimingHelpers::timer(), and plotDoE::x.

Referenced by oomph::CG< MATRIX >::solve().

Member Data Documentation

◆ Iterations

template<typename MATRIX >
unsigned oomph::CG< MATRIX >::Iterations
private

Number of iterations taken.

Referenced by oomph::CG< MATRIX >::iterations().

◆ Matrix_can_be_deleted

template<typename MATRIX >
bool oomph::CG< MATRIX >::Matrix_can_be_deleted
private

Boolean flag to indicate if the matrix pointed to be Matrix_pt can be deleted.

Referenced by oomph::CG< MATRIX >::clean_up_memory(), and oomph::CG< MATRIX >::solve().

◆ Matrix_pt

template<typename MATRIX >
MATRIX* oomph::CG< MATRIX >::Matrix_pt
private

◆ Resolving

template<typename MATRIX >
bool oomph::CG< MATRIX >::Resolving
private

Boolean flag to indicate if the solve is done in re-solve mode, bypassing setup of matrix and preconditioner

Referenced by oomph::CG< MATRIX >::solve().


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