linear_solver.h
Go to the documentation of this file.
1 // LIC// ====================================================================
2 // LIC// This file forms part of oomph-lib, the object-oriented,
3 // LIC// multi-physics finite-element library, available
4 // LIC// at http://www.oomph-lib.org.
5 // LIC//
6 // LIC// Copyright (C) 2006-2022 Matthias Heil and Andrew Hazel
7 // LIC//
8 // LIC// This library is free software; you can redistribute it and/or
9 // LIC// modify it under the terms of the GNU Lesser General Public
10 // LIC// License as published by the Free Software Foundation; either
11 // LIC// version 2.1 of the License, or (at your option) any later version.
12 // LIC//
13 // LIC// This library is distributed in the hope that it will be useful,
14 // LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // LIC// Lesser General Public License for more details.
17 // LIC//
18 // LIC// You should have received a copy of the GNU Lesser General Public
19 // LIC// License along with this library; if not, write to the Free Software
20 // LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // LIC// 02110-1301 USA.
22 // LIC//
23 // LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 // LIC//
25 // LIC//====================================================================
26 
27 // This header defines a class for linear solvers
28 
29 // Include guards
30 #ifndef OOMPH_LINEAR_SOLVER_HEADER
31 #define OOMPH_LINEAR_SOLVER_HEADER
32 
33 
34 // Config header generated by autoconfig
35 #ifdef HAVE_CONFIG_H
36 #include <oomph-lib-config.h>
37 #endif
38 
39 #ifdef OOMPH_HAS_MPI
40 #include "mpi.h"
41 #endif
42 
43 // oomph-lib headers
44 #include "Vector.h"
45 #include "double_vector.h"
46 #include "matrices.h"
47 
48 namespace oomph
49 {
50  // Forward declaration of problem class
51  class Problem;
52 
53  //====================================================================
66  //====================================================================
68  {
69  protected:
74 
76  // for the solves should be documented
77  bool Doc_time;
78 
82 
85 
89 
90  public:
93  : Enable_resolve(false),
94  Doc_time(true),
95  Compute_gradient(false),
97  {
98  }
99 
101  LinearSolver(const LinearSolver& dummy) = delete;
102 
104  void operator=(const LinearSolver&) = delete;
105 
107  virtual ~LinearSolver() {}
108 
111  {
112  Doc_time = true;
113  }
114 
117  {
118  Doc_time = false;
119  }
120 
122  bool is_doc_time_enabled() const
123  {
124  return Doc_time;
125  }
126 
128  bool is_resolve_enabled() const
129  {
130  return Enable_resolve;
131  }
132 
135  virtual void enable_resolve()
136  {
137  Enable_resolve = true;
138  }
139 
144  virtual void disable_resolve()
145  {
146  Enable_resolve = false;
147  }
148 
152  virtual void solve(Problem* const& problem_pt, DoubleVector& result) = 0;
153 
156  virtual void solve(DoubleMatrixBase* const& matrix_pt,
157  const DoubleVector& rhs,
158  DoubleVector& result)
159  {
160  throw OomphLibError(
161  "DoubleVector based solve function not implemented for this solver",
164  }
165 
168  virtual void solve(DoubleMatrixBase* const& matrix_pt,
169  const Vector<double>& rhs,
170  Vector<double>& result)
171  {
172  throw OomphLibError(
173  "Vector<double> based solve function not implemented for this solver",
176  }
177 
181  virtual void solve_transpose(Problem* const& problem_pt,
182  DoubleVector& result)
183  {
184  // Create an output stream
185  std::ostringstream error_message_stream;
186 
187  // Create the error message
188  error_message_stream << "The function to solve the transposed system has "
189  << "not yet been\nimplemented for this solver."
190  << std::endl;
191 
192  // Throw the error message
193  throw OomphLibError(error_message_stream.str(),
196  } // End of solve_transpose
197 
200  virtual void solve_transpose(DoubleMatrixBase* const& matrix_pt,
201  const DoubleVector& rhs,
202  DoubleVector& result)
203  {
204  throw OomphLibError(
205  "DoubleVector based solve function not implemented for this solver",
208  }
209 
212  virtual void solve_transpose(DoubleMatrixBase* const& matrix_pt,
213  const Vector<double>& rhs,
214  Vector<double>& result)
215  {
216  throw OomphLibError(
217  "Vector<double> based solve function not implemented for this solver",
220  }
221 
225  virtual void resolve(const DoubleVector& rhs, DoubleVector& result)
226  {
227  throw OomphLibError(
228  "Resolve function not implemented for this linear solver",
231  }
232 
236  virtual void resolve_transpose(const DoubleVector& rhs,
237  DoubleVector& result)
238  {
239  // Create an output stream
240  std::ostringstream error_message_stream;
241 
242  // Create the error message
243  error_message_stream
244  << "The function to resolve the transposed system has "
245  << "not yet been\nimplemented for this solver." << std::endl;
246 
247  // Throw the error message
248  throw OomphLibError(error_message_stream.str(),
251  } // End of resolve_transpose
252 
256  virtual void clean_up_memory() {}
257 
260  virtual double jacobian_setup_time() const
261  {
262  throw OomphLibError(
263  "jacobian_setup_time has not been implemented for this linear solver",
266  return 0;
267  }
268 
271  virtual double linear_solver_solution_time() const
272  {
273  throw OomphLibError(
274  "linear_solver_solution_time() not implemented for this linear solver",
277  return 0;
278  }
279 
283  {
284  throw OomphLibError(
285  "enable_computation_of_gradient() not implemented for "
286  "this linear solver",
289  }
290 
294  {
295  Compute_gradient = false;
296  }
297 
301  {
303  }
304 
306  void get_gradient(DoubleVector& gradient)
307  {
308 #ifdef PARANOID
310  {
311 #endif
313 #ifdef PARANOID
314  }
315  else
316  {
317  throw OomphLibError(
318  "The gradient has not been computed for this linear solver!",
321  }
322 #endif
323  }
324  };
325 
326  //=============================================================================
332  //============================================================================
333  class DenseLU : public LinearSolver
334  {
336  friend class DenseDoubleMatrix;
337 
338  public:
341  : Jacobian_setup_time(0.0),
342  Solution_time(0.0),
344  Index(0),
345  LU_factors(0)
346  {
347  // Shut up!
348  Doc_time = false;
349  }
350 
352  DenseLU(const DenseLU& dummy) = delete;
353 
355  void operator=(const DenseLU&) = delete;
356 
359  {
360  clean_up_memory();
361  }
362 
366  void solve(Problem* const& problem_pt, DoubleVector& result);
367 
370  void solve(DoubleMatrixBase* const& matrix_pt,
371  const DoubleVector& rhs,
372  DoubleVector& result);
373 
376  void solve(DoubleMatrixBase* const& matrix_pt,
377  const Vector<double>& rhs,
378  Vector<double>& result);
379 
382  double jacobian_setup_time() const
383  {
384  return Jacobian_setup_time;
385  }
386 
389  virtual double linear_solver_solution_time() const
390  {
391  return Solution_time;
392  }
393 
394  protected:
396  void factorise(DoubleMatrixBase* const& matrix_pt);
397 
399  void backsub(const DoubleVector& rhs, DoubleVector& result);
400 
402  void backsub(const Vector<double>& rhs, Vector<double>& result);
403 
405  void clean_up_memory();
406 
409 
412 
416 
417  private:
419  long* Index;
420 
422  double* LU_factors;
423  };
424 
425 
426  //====================================================================
430  //====================================================================
431  class FD_LU : public DenseLU
432  {
433  public:
435  FD_LU() : DenseLU() {}
436 
438  FD_LU(const FD_LU& dummy) = delete;
439 
441  void operator=(const FD_LU&) = delete;
442 
446  void solve(Problem* const& problem_pt, DoubleVector& result);
447 
450  void solve(DoubleMatrixBase* const& matrix_pt,
451  const DoubleVector& rhs,
452  DoubleVector& result)
453  {
454  DenseLU::solve(matrix_pt, rhs, result);
455  }
456 
461  void solve(DoubleMatrixBase* const& matrix_pt,
462  const Vector<double>& rhs,
463  Vector<double>& result)
464  {
465  LinearSolver::solve(matrix_pt, rhs, result);
466  }
467  };
468 
469 
473 
474 
475  //=============================================================================
484  //=============================================================================
486  {
487  public:
492  enum Type
493  {
497  };
498 
501  {
502  // Set solver wide default values and null pointers
503  Doc_stats = false;
504  Suppress_solve = false;
505  Using_dist = false;
507 
508 #ifdef OOMPH_HAS_MPI
509  // Set default values and nullify pointers for SuperLU Dist
510  Dist_use_global_solver = false;
511  Dist_delete_matrix_data = false;
512  Dist_allow_row_and_col_permutations = true;
513  Dist_solver_data_pt = 0;
514  Dist_global_solve_data_allocated = false;
515  Dist_distributed_solve_data_allocated = false;
516  Dist_value_pt = 0;
517  Dist_index_pt = 0;
518  Dist_start_pt = 0;
519 #endif
520 
521  // Set default values and null pointers for SuperLU (serial)
524  Serial_n_dof = 0;
525  }
526 
528  SuperLUSolver(const SuperLUSolver& dummy) = delete;
529 
531  void operator=(const SuperLUSolver&) = delete;
532 
535  {
536  clean_up_memory();
537  }
538 
541  {
542  Compute_gradient = true;
543  }
544 
545  // SuperLUSolver methods
547 
550  {
552  clean_up_memory();
553  }
554 
558  void solve(Problem* const& problem_pt, DoubleVector& result);
559 
565  void solve(DoubleMatrixBase* const& matrix_pt,
566  const DoubleVector& rhs,
567  DoubleVector& result);
568 
569 
570  /* /// Linear-algebra-type solver: Takes pointer to a matrix */
571  /* /// and rhs vector and returns the solution of the linear system */
572  /* /// Call the broken base-class version. If you want this, please */
573  /* /// implement it */
574  /* void solve(DoubleMatrixBase* const &matrix_pt, */
575  /* const Vector<double> &rhs, */
576  /* Vector<double> &result) */
577  /* {LinearSolver::solve(matrix_pt,rhs,result);} */
578 
582  void solve_transpose(Problem* const& problem_pt, DoubleVector& result);
583 
589  void solve_transpose(DoubleMatrixBase* const& matrix_pt,
590  const DoubleVector& rhs,
591  DoubleVector& result);
592 
596  void resolve(const DoubleVector& rhs, DoubleVector& result);
597 
600  void resolve_transpose(const DoubleVector& rhs, DoubleVector& result);
601 
604  {
605  Doc_stats = true;
606  }
607 
610  {
611  Doc_stats = false;
612  }
613 
616  double jacobian_setup_time() const
617  {
618  return Jacobian_setup_time;
619  }
620 
623  virtual double linear_solver_solution_time() const
624  {
625  return Solution_time;
626  }
627 
631  void factorise(DoubleMatrixBase* const& matrix_pt);
632 
635  void backsub(const DoubleVector& rhs, DoubleVector& result);
636 
639  void backsub_transpose(const DoubleVector& rhs, DoubleVector& result);
640 
642  void clean_up_memory();
643 
646  void set_solver_type(const Type& t)
647  {
648  this->clean_up_memory();
649  Solver_type = t;
650  }
651 
652  // SuperLU (serial) methods
654 
657  {
659  }
660 
663  {
665  }
666 
667 #ifdef OOMPH_HAS_MPI
668 
669  // SuperLU Dist methods
671 
678  void enable_delete_matrix_data_in_superlu_dist()
679  {
680  Dist_delete_matrix_data = true;
681  }
682 
686  void disable_delete_matrix_data_in_superlu_dist()
687  {
688  Dist_delete_matrix_data = false;
689  }
690 
694  void enable_row_and_col_permutations_in_superlu_dist()
695  {
696  Dist_allow_row_and_col_permutations = true;
697  }
698 
701  void disable_row_and_col_permutations_in_superlu_dist()
702  {
703  Dist_allow_row_and_col_permutations = false;
704  }
705 
710  void use_global_solve_in_superlu_dist()
711  {
712  if (!Dist_use_global_solver)
713  {
714  clean_up_memory();
715  Dist_use_global_solver = true;
716  }
717  }
718 
723  void use_distributed_solve_in_superlu_dist()
724  {
725  if (Dist_use_global_solver)
726  {
727  clean_up_memory();
728  Dist_use_global_solver = false;
729  }
730  }
731 
732 #endif
733 
734  private:
736  void factorise_serial(DoubleMatrixBase* const& matrix_pt);
737 
739  void backsub_serial(const DoubleVector& rhs, DoubleVector& result);
740 
742  void backsub_transpose_serial(const DoubleVector& rhs,
743  DoubleVector& result);
744 
745 #ifdef OOMPH_HAS_MPI
747  void factorise_distributed(DoubleMatrixBase* const& matrix_pt);
748 
750  void backsub_distributed(const DoubleVector& rhs, DoubleVector& result);
751 
753  void backsub_transpose_distributed(const DoubleVector& rhs,
754  DoubleVector& result);
755 #endif
756 
757  // SuperLUSolver member data
759 
762 
765 
768 
770  bool Doc_stats;
771 
774 
777 
778  // SuperLU (serial) member data
780 
783 
786 
788  unsigned long Serial_n_dof;
789 
792 
795 
796  public:
799 
801  double get_total_needed_memory();
802 
803  private:
804 #ifdef OOMPH_HAS_MPI
805 
806  // SuperLU Dist member data
808  public:
811  static bool Suppress_incorrect_rhs_distribution_warning_in_resolve;
812 
813  private:
817  bool Dist_use_global_solver;
818 
820  bool Dist_global_solve_data_allocated;
821 
823  bool Dist_distributed_solve_data_allocated;
824 
826  void* Dist_solver_data_pt;
827 
829  int Dist_nprow;
830 
832  int Dist_npcol;
833 
835  int Dist_info;
836 
841  bool Dist_allow_row_and_col_permutations;
842 
849  bool Dist_delete_matrix_data;
850 
852  double* Dist_value_pt;
853 
856  int* Dist_index_pt;
857 
859  // required by SuperLU_DIST
860  int* Dist_start_pt;
861 
862 #endif
863  }; // end of SuperLUSolver
864 } // namespace oomph
865 #endif
std::vector< double > DoubleVector
loads clump configuration
Definition: ClumpInput.h:26
Definition: matrices.h:1271
Definition: linear_solver.h:334
~DenseLU()
Destructor, clean up the stored LU factors.
Definition: linear_solver.h:358
double Jacobian_setup_time
Jacobian setup time.
Definition: linear_solver.h:408
double jacobian_setup_time() const
Definition: linear_solver.h:382
void backsub(const DoubleVector &rhs, DoubleVector &result)
Do the backsubstitution step to solve the system LU result = rhs.
Definition: linear_solver.cc:320
void clean_up_memory()
Clean up the stored LU factors.
Definition: linear_solver.cc:106
long * Index
Pointer to storage for the index of permutations in the LU solve.
Definition: linear_solver.h:419
DenseLU()
Constructor, initialise storage.
Definition: linear_solver.h:340
void factorise(DoubleMatrixBase *const &matrix_pt)
Perform the LU decomposition of the matrix.
Definition: linear_solver.cc:131
double * LU_factors
Pointer to storage for the LU decomposition.
Definition: linear_solver.h:422
void operator=(const DenseLU &)=delete
Broken assignment operator.
virtual double linear_solver_solution_time() const
Definition: linear_solver.h:389
double Solution_time
Solution time.
Definition: linear_solver.h:411
void solve(Problem *const &problem_pt, DoubleVector &result)
Definition: linear_solver.cc:51
DenseLU(const DenseLU &dummy)=delete
Broken copy constructor.
int Sign_of_determinant_of_matrix
Definition: linear_solver.h:415
Definition: linear_algebra_distribution.h:435
Definition: matrices.h:261
Definition: double_vector.h:58
void clear()
wipes the DoubleVector
Definition: double_vector.h:142
Definition: linear_solver.h:432
FD_LU()
Constructor: empty.
Definition: linear_solver.h:435
void solve(DoubleMatrixBase *const &matrix_pt, const Vector< double > &rhs, Vector< double > &result)
Definition: linear_solver.h:461
void solve(Problem *const &problem_pt, DoubleVector &result)
Definition: linear_solver.cc:575
FD_LU(const FD_LU &dummy)=delete
Broken copy constructor.
void operator=(const FD_LU &)=delete
Broken assignment operator.
void solve(DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &result)
Definition: linear_solver.h:450
Definition: linear_solver.h:68
void operator=(const LinearSolver &)=delete
Broken assignment operator.
virtual double jacobian_setup_time() const
Definition: linear_solver.h:260
virtual void solve(Problem *const &problem_pt, DoubleVector &result)=0
virtual void solve(DoubleMatrixBase *const &matrix_pt, const Vector< double > &rhs, Vector< double > &result)
Definition: linear_solver.h:168
virtual void enable_resolve()
Definition: linear_solver.h:135
virtual void enable_computation_of_gradient()
Definition: linear_solver.h:282
virtual void resolve(const DoubleVector &rhs, DoubleVector &result)
Definition: linear_solver.h:225
virtual double linear_solver_solution_time() const
Definition: linear_solver.h:271
bool is_doc_time_enabled() const
Is documentation of solve times enabled?
Definition: linear_solver.h:122
virtual void solve_transpose(DoubleMatrixBase *const &matrix_pt, const Vector< double > &rhs, Vector< double > &result)
Definition: linear_solver.h:212
bool Doc_time
Boolean flag that indicates whether the time taken.
Definition: linear_solver.h:77
virtual void solve(DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &result)
Definition: linear_solver.h:156
bool Enable_resolve
Definition: linear_solver.h:73
virtual void solve_transpose(DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &result)
Definition: linear_solver.h:200
void get_gradient(DoubleVector &gradient)
function to access the gradient, provided it has been computed
Definition: linear_solver.h:306
LinearSolver(const LinearSolver &dummy)=delete
Broken copy constructor.
LinearSolver()
Empty constructor, initialise the member data.
Definition: linear_solver.h:92
void disable_computation_of_gradient()
Definition: linear_solver.h:293
virtual void solve_transpose(Problem *const &problem_pt, DoubleVector &result)
Definition: linear_solver.h:181
void disable_doc_time()
Disable documentation of solve times.
Definition: linear_solver.h:116
virtual ~LinearSolver()
Empty virtual destructor.
Definition: linear_solver.h:107
virtual void clean_up_memory()
Definition: linear_solver.h:256
bool Gradient_has_been_computed
flag that indicates whether the gradient was computed or not
Definition: linear_solver.h:84
void enable_doc_time()
Enable documentation of solve times.
Definition: linear_solver.h:110
void reset_gradient()
Definition: linear_solver.h:300
virtual void resolve_transpose(const DoubleVector &rhs, DoubleVector &result)
Definition: linear_solver.h:236
DoubleVector Gradient_for_glob_conv_newton_solve
Definition: linear_solver.h:88
virtual void disable_resolve()
Definition: linear_solver.h:144
bool is_resolve_enabled() const
Boolean flag indicating if resolves are enabled.
Definition: linear_solver.h:128
bool Compute_gradient
Definition: linear_solver.h:81
Definition: oomph_definitions.h:222
Definition: problem.h:151
Definition: linear_solver.h:486
SuperLUSolver(const SuperLUSolver &dummy)=delete
Broken copy constructor.
bool Doc_stats
Set to true to output statistics (false by default).
Definition: linear_solver.h:770
void solve_transpose(Problem *const &problem_pt, DoubleVector &result)
Definition: linear_solver.cc:1293
Type Solver_type
the solver type. see SuperLU_solver_type for details.
Definition: linear_solver.h:773
void operator=(const SuperLUSolver &)=delete
Broken assignment operator.
virtual double linear_solver_solution_time() const
Definition: linear_solver.h:623
void backsub_serial(const DoubleVector &rhs, DoubleVector &result)
backsub method for SuperLU (serial)
Definition: linear_solver.cc:2503
void enable_doc_stats()
Enable documentation of solver statistics.
Definition: linear_solver.h:603
double Solution_time
Solution time.
Definition: linear_solver.h:764
bool Serial_compressed_row_flag
Use compressed row version?
Definition: linear_solver.h:794
Type
Definition: linear_solver.h:493
@ Distributed
Definition: linear_solver.h:496
@ Serial
Definition: linear_solver.h:495
@ Default
Definition: linear_solver.h:494
void solve(Problem *const &problem_pt, DoubleVector &result)
Definition: linear_solver.cc:814
void factorise(DoubleMatrixBase *const &matrix_pt)
Definition: linear_solver.cc:1820
void factorise_serial(DoubleMatrixBase *const &matrix_pt)
factorise method for SuperLU (serial)
Definition: linear_solver.cc:2161
bool Using_dist
boolean flag indicating whether superlu dist is being used
Definition: linear_solver.h:776
unsigned long Serial_n_dof
The number of unknowns in the linear system.
Definition: linear_solver.h:788
void set_solver_type(const Type &t)
Definition: linear_solver.h:646
void * Serial_f_factors
Storage for the LU factors as required by SuperLU.
Definition: linear_solver.h:782
void resolve_transpose(const DoubleVector &rhs, DoubleVector &result)
Resolve the (transposed) system for a given RHS.
Definition: linear_solver.cc:1793
SuperLUSolver()
Constructor. Set the defaults.
Definition: linear_solver.h:500
bool Suppress_solve
Suppress solve?
Definition: linear_solver.h:767
~SuperLUSolver()
Destructor, clean up the stored matrices.
Definition: linear_solver.h:534
double jacobian_setup_time() const
Definition: linear_solver.h:616
int Serial_sign_of_determinant_of_matrix
Sign of the determinant of the matrix.
Definition: linear_solver.h:791
double get_memory_usage_for_lu_factors()
How much memory do the LU factors take up? In bytes.
Definition: linear_solver.cc:758
void use_compressed_column_for_superlu_serial()
Use the compressed column format in superlu serial.
Definition: linear_solver.h:662
void disable_resolve()
Overload disable resolve so that it cleans up memory too.
Definition: linear_solver.h:549
double get_total_needed_memory()
How much memory was allocated by SuperLU? In bytes.
Definition: linear_solver.cc:786
double Jacobian_setup_time
Jacobian setup time.
Definition: linear_solver.h:761
void backsub_transpose_serial(const DoubleVector &rhs, DoubleVector &result)
backsub method for SuperLU (serial)
Definition: linear_solver.cc:2593
void resolve(const DoubleVector &rhs, DoubleVector &result)
Resolve the system for a given RHS.
Definition: linear_solver.cc:1769
void use_compressed_row_for_superlu_serial()
Use the compressed row format in superlu serial.
Definition: linear_solver.h:656
void disable_doc_stats()
Disable documentation of solver statistics.
Definition: linear_solver.h:609
void backsub(const DoubleVector &rhs, DoubleVector &result)
Definition: linear_solver.cc:2292
void enable_computation_of_gradient()
function to enable the computation of the gradient
Definition: linear_solver.h:540
void clean_up_memory()
Clean up the memory allocated by the solver.
Definition: linear_solver.cc:2683
void backsub_transpose(const DoubleVector &rhs, DoubleVector &result)
Definition: linear_solver.cc:2312
int Serial_info
Info flag for the SuperLU solver.
Definition: linear_solver.h:785
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
t
Definition: plotPSD.py:36
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86