oomph::SuperLUSolver Class Reference

#include <linear_solver.h>

+ Inheritance diagram for oomph::SuperLUSolver:

Public Types

enum  Type { Default , Serial , Distributed }
 

Public Member Functions

 SuperLUSolver ()
 Constructor. Set the defaults. More...
 
 SuperLUSolver (const SuperLUSolver &dummy)=delete
 Broken copy constructor. More...
 
void operator= (const SuperLUSolver &)=delete
 Broken assignment operator. More...
 
 ~SuperLUSolver ()
 Destructor, clean up the stored matrices. More...
 
void enable_computation_of_gradient ()
 function to enable the computation of the gradient 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 &result)
 
void solve_transpose (Problem *const &problem_pt, DoubleVector &result)
 
void solve_transpose (DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &result)
 
void resolve (const DoubleVector &rhs, DoubleVector &result)
 Resolve the system for a given RHS. More...
 
void resolve_transpose (const DoubleVector &rhs, DoubleVector &result)
 Resolve the (transposed) system for a given RHS. More...
 
void enable_doc_stats ()
 Enable documentation of solver statistics. More...
 
void disable_doc_stats ()
 Disable documentation of solver statistics. More...
 
double jacobian_setup_time () const
 
virtual double linear_solver_solution_time () const
 
void factorise (DoubleMatrixBase *const &matrix_pt)
 
void backsub (const DoubleVector &rhs, DoubleVector &result)
 
void backsub_transpose (const DoubleVector &rhs, DoubleVector &result)
 
void clean_up_memory ()
 Clean up the memory allocated by the solver. More...
 
void set_solver_type (const Type &t)
 
void use_compressed_row_for_superlu_serial ()
 Use the compressed row format in superlu serial. More...
 
void use_compressed_column_for_superlu_serial ()
 Use the compressed column format in superlu serial. More...
 
double get_memory_usage_for_lu_factors ()
 How much memory do the LU factors take up? In bytes. More...
 
double get_total_needed_memory ()
 How much memory was allocated by SuperLU? In bytes. More...
 
- 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 (DoubleMatrixBase *const &matrix_pt, const Vector< double > &rhs, Vector< double > &result)
 
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 factorise_serial (DoubleMatrixBase *const &matrix_pt)
 factorise method for SuperLU (serial) More...
 
void backsub_serial (const DoubleVector &rhs, DoubleVector &result)
 backsub method for SuperLU (serial) More...
 
void backsub_transpose_serial (const DoubleVector &rhs, DoubleVector &result)
 backsub method for SuperLU (serial) More...
 

Private Attributes

double Jacobian_setup_time
 Jacobian setup time. More...
 
double Solution_time
 Solution time. More...
 
bool Suppress_solve
 Suppress solve? More...
 
bool Doc_stats
 Set to true to output statistics (false by default). More...
 
Type Solver_type
 the solver type. see SuperLU_solver_type for details. More...
 
bool Using_dist
 boolean flag indicating whether superlu dist is being used More...
 
void * Serial_f_factors
 Storage for the LU factors as required by SuperLU. More...
 
int Serial_info
 Info flag for the SuperLU solver. More...
 
unsigned long Serial_n_dof
 The number of unknowns in the linear system. More...
 
int Serial_sign_of_determinant_of_matrix
 Sign of the determinant of the matrix. More...
 
bool Serial_compressed_row_flag
 Use compressed row version? More...
 

Additional Inherited Members

- Protected Member Functions inherited from oomph::DistributableLinearAlgebraObject
void clear_distribution ()
 
- 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
 

Detailed Description

//////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// SuperLU Project Solver class. This is a combined wrapper for both SuperLU and SuperLU Dist. See http://crd.lbl.gov/~xiaoye/SuperLU/ Default Behaviour: If this solver is distributed over more than one processor then SuperLU Dist is used. Member data naming convention: member data associated with the SuperLU Dist solver begins Dist_... and member data associated with the serial SuperLU solver begins Serial_... .

Member Enumeration Documentation

◆ Type

enum type to specify the solver behaviour. Default - will employ superlu dist if more than 1 processor. Serial - will always try use superlu (serial). Distributed - will always try to use superlu dist.

Enumerator
Default 
Serial 
Distributed 
493  {
494  Default,
495  Serial,
497  };
@ Distributed
Definition: linear_solver.h:496
@ Serial
Definition: linear_solver.h:495
@ Default
Definition: linear_solver.h:494

Constructor & Destructor Documentation

◆ SuperLUSolver() [1/2]

oomph::SuperLUSolver::SuperLUSolver ( )
inline

Constructor. Set the defaults.

500  : Serial_f_factors(0)
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  }
bool Doc_stats
Set to true to output statistics (false by default).
Definition: linear_solver.h:770
Type Solver_type
the solver type. see SuperLU_solver_type for details.
Definition: linear_solver.h:773
bool Serial_compressed_row_flag
Use compressed row version?
Definition: linear_solver.h:794
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 * Serial_f_factors
Storage for the LU factors as required by SuperLU.
Definition: linear_solver.h:782
bool Suppress_solve
Suppress solve?
Definition: linear_solver.h:767
int Serial_sign_of_determinant_of_matrix
Sign of the determinant of the matrix.
Definition: linear_solver.h:791

References Default, Doc_stats, Serial_compressed_row_flag, Serial_n_dof, Serial_sign_of_determinant_of_matrix, Solver_type, Suppress_solve, and Using_dist.

◆ SuperLUSolver() [2/2]

oomph::SuperLUSolver::SuperLUSolver ( const SuperLUSolver dummy)
delete

Broken copy constructor.

◆ ~SuperLUSolver()

oomph::SuperLUSolver::~SuperLUSolver ( )
inline

Destructor, clean up the stored matrices.

535  {
536  clean_up_memory();
537  }
void clean_up_memory()
Clean up the memory allocated by the solver.
Definition: linear_solver.cc:2683

References clean_up_memory().

Member Function Documentation

◆ backsub()

void oomph::SuperLUSolver::backsub ( const DoubleVector rhs,
DoubleVector result 
)

Do the backsubstitution for SuperLU solver Note: returns the global result Vector.

Do the backsubstitution for SuperLUSolver. Note - this method performs no paranoid checks - these are all performed in solve(...) and resolve(...)

2293  {
2294 #ifdef OOMPH_HAS_MPI
2295  if (Using_dist)
2296  {
2297  backsub_distributed(rhs, result);
2298  }
2299  else
2300 #endif
2301  {
2302  backsub_serial(rhs, result);
2303  }
2304  }
void backsub_serial(const DoubleVector &rhs, DoubleVector &result)
backsub method for SuperLU (serial)
Definition: linear_solver.cc:2503

References backsub_serial(), and Using_dist.

Referenced by resolve(), and solve().

◆ backsub_serial()

void oomph::SuperLUSolver::backsub_serial ( const DoubleVector rhs,
DoubleVector result 
)
private

backsub method for SuperLU (serial)

Do the backsubstitution for SuperLU.

2505  {
2506  // Find the number of unknowns
2507  int n = rhs.nrow();
2508 
2509 #ifdef PARANOID
2510  // PARANOID check that this rhs distribution is setup
2511  if (!rhs.built())
2512  {
2513  std::ostringstream error_message_stream;
2514  error_message_stream << "The rhs vector distribution must be setup.";
2515  throw OomphLibError(error_message_stream.str(),
2518  }
2519  // PARANOID check that the rhs has the right number of global rows
2520  if (static_cast<int>(Serial_n_dof) != n)
2521  {
2522  throw OomphLibError(
2523  "RHS does not have the same dimension as the linear system",
2526  }
2527  // PARANOID check that the rhs is not distributed
2528  if (rhs.distribution_pt()->distributed())
2529  {
2530  std::ostringstream error_message_stream;
2531  error_message_stream << "The rhs vector must not be distributed.";
2532  throw OomphLibError(error_message_stream.str(),
2535  }
2536  // PARANOID check that if the result is setup it matches the distribution
2537  // of the rhs
2538  if (result.built())
2539  {
2540  if (!(*rhs.distribution_pt() == *result.distribution_pt()))
2541  {
2542  std::ostringstream error_message_stream;
2543  error_message_stream << "If the result distribution is setup then it "
2544  "must be the same as the "
2545  << "rhs distribution";
2546  throw OomphLibError(error_message_stream.str(),
2549  }
2550  }
2551 #endif
2552 
2553  // copy result to rhs
2554  result = rhs;
2555 
2556  // Number of RHSs
2557  int nrhs = 1;
2558 
2559  // Cast the boolean flags to ints for SuperLU
2561  int doc = Doc_stats;
2562 
2563  // Do the backsubsitition phase
2564  int i = 2;
2565  superlu(&i,
2566  &n,
2567  0,
2568  &nrhs,
2569  0,
2570  0,
2571  0,
2572  result.values_pt(),
2573  &n,
2574  &transpose,
2575  &doc,
2577  &Serial_info);
2578 
2579  // Throw an error if superLU returned an error status in info.
2580  if (Serial_info != 0)
2581  {
2582  std::ostringstream error_msg;
2583  error_msg << "SuperLU returned the error status code " << Serial_info
2584  << " . See the SuperLU documentation for what this means.";
2585  throw OomphLibError(
2587  }
2588  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
int Serial_info
Info flag for the SuperLU solver.
Definition: linear_solver.h:785
void transpose()
Definition: skew_symmetric_matrix3.cpp:135
int superlu(int *, int *, int *, int *, double *, int *, int *, double *, int *, int *, int *, void *, int *)
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References oomph::DoubleVector::built(), oomph::LinearAlgebraDistribution::distributed(), oomph::DistributableLinearAlgebraObject::distribution_pt(), Doc_stats, i, n, oomph::DistributableLinearAlgebraObject::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, Serial_compressed_row_flag, Serial_f_factors, Serial_info, Serial_n_dof, oomph::superlu(), anonymous_namespace{skew_symmetric_matrix3.cpp}::transpose(), and oomph::DoubleVector::values_pt().

Referenced by backsub().

◆ backsub_transpose()

void oomph::SuperLUSolver::backsub_transpose ( const DoubleVector rhs,
DoubleVector result 
)

Do the back-substitution for transposed system of the SuperLU solver Note: Returns the global result Vector.

Do the backsubstitution of the transposed system for SuperLUSolver. Note - this method performs no paranoid checks - these are all performed in solve(...) and resolve(...)

2314  {
2315 #ifdef OOMPH_HAS_MPI
2316  if (Using_dist)
2317  {
2318  backsub_transpose_distributed(rhs, result);
2319  }
2320  else
2321 #endif
2322  {
2323  backsub_transpose_serial(rhs, result);
2324  }
2325  }
void backsub_transpose_serial(const DoubleVector &rhs, DoubleVector &result)
backsub method for SuperLU (serial)
Definition: linear_solver.cc:2593

References backsub_transpose_serial(), and Using_dist.

Referenced by resolve_transpose(), and solve_transpose().

◆ backsub_transpose_serial()

void oomph::SuperLUSolver::backsub_transpose_serial ( const DoubleVector rhs,
DoubleVector result 
)
private

backsub method for SuperLU (serial)

Do the backsubstitution for SuperLU.

2595  {
2596  // Find the number of unknowns
2597  int n = rhs.nrow();
2598 
2599 #ifdef PARANOID
2600  // PARANOID check that this rhs distribution is setup
2601  if (!rhs.built())
2602  {
2603  std::ostringstream error_message_stream;
2604  error_message_stream << "The rhs vector distribution must be setup.";
2605  throw OomphLibError(error_message_stream.str(),
2608  }
2609  // PARANOID check that the rhs has the right number of global rows
2610  if (static_cast<int>(Serial_n_dof) != n)
2611  {
2612  throw OomphLibError(
2613  "RHS does not have the same dimension as the linear system",
2616  }
2617  // PARANOID check that the rhs is not distributed
2618  if (rhs.distribution_pt()->distributed())
2619  {
2620  std::ostringstream error_message_stream;
2621  error_message_stream << "The rhs vector must not be distributed.";
2622  throw OomphLibError(error_message_stream.str(),
2625  }
2626  // PARANOID check that if the result is setup it matches the distribution
2627  // of the rhs
2628  if (result.built())
2629  {
2630  if (!(*rhs.distribution_pt() == *result.distribution_pt()))
2631  {
2632  std::ostringstream error_message_stream;
2633  error_message_stream << "If the result distribution is setup then it "
2634  "must be the same as the "
2635  << "rhs distribution";
2636  throw OomphLibError(error_message_stream.str(),
2639  }
2640  }
2641 #endif
2642 
2643  // copy result to rhs
2644  result = rhs;
2645 
2646  // Number of RHSs
2647  int nrhs = 1;
2648 
2649  // Cast the boolean flags to ints for SuperLU
2651  int doc = Doc_stats;
2652 
2653  // Do the backsubsitition phase
2654  int i = 2;
2655  superlu(&i,
2656  &n,
2657  0,
2658  &nrhs,
2659  0,
2660  0,
2661  0,
2662  result.values_pt(),
2663  &n,
2664  &transpose,
2665  &doc,
2667  &Serial_info);
2668 
2669  // Throw an error if superLU returned an error status in info.
2670  if (Serial_info != 0)
2671  {
2672  std::ostringstream error_msg;
2673  error_msg << "SuperLU returned the error status code " << Serial_info
2674  << " . See the SuperLU documentation for what this means.";
2675  throw OomphLibError(
2677  }
2678  }

References oomph::DoubleVector::built(), oomph::LinearAlgebraDistribution::distributed(), oomph::DistributableLinearAlgebraObject::distribution_pt(), Doc_stats, i, n, oomph::DistributableLinearAlgebraObject::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, Serial_compressed_row_flag, Serial_f_factors, Serial_info, Serial_n_dof, oomph::superlu(), anonymous_namespace{skew_symmetric_matrix3.cpp}::transpose(), and oomph::DoubleVector::values_pt().

Referenced by backsub_transpose().

◆ clean_up_memory()

void oomph::SuperLUSolver::clean_up_memory ( )
virtual

Clean up the memory allocated by the solver.

Clean up the memory.

Reimplemented from oomph::LinearSolver.

2684  {
2685  // If we have non-zero LU factors stored
2686  if (Serial_f_factors != 0)
2687  {
2688  // Clean up those factors
2689  int i = 3;
2691  superlu(&i,
2692  0,
2693  0,
2694  0,
2695  0,
2696  0,
2697  0,
2698  0,
2699  0,
2700  &transpose,
2701  0,
2703  &Serial_info);
2704 
2705  // Set the F_factors to zero
2706  Serial_f_factors = 0;
2707  Serial_n_dof = 0;
2708  }
2709 
2710 #ifdef OOMPH_HAS_MPI
2711  // If we have non-zero LU factors stored
2712  if (Dist_solver_data_pt != 0)
2713  {
2714  // Clean up any stored solver data
2715 
2716  // Doc (0/1) = (true/false)
2717  int doc = !Doc_stats;
2718 
2719  // Reset Info flag
2720  Dist_info = 0;
2721 
2722  // number of DOFs
2723  int ndof = this->distribution_pt()->nrow();
2724 
2725  if (Dist_distributed_solve_data_allocated)
2726  {
2727  superlu_dist_distributed_matrix(
2728  3,
2729  -1,
2730  ndof,
2731  0,
2732  0,
2733  0,
2734  0,
2735  0,
2736  0,
2737  0,
2738  Dist_nprow,
2739  Dist_npcol,
2740  doc,
2741  &Dist_solver_data_pt,
2742  &Dist_info,
2743  this->distribution_pt()->communicator_pt()->mpi_comm());
2744  Dist_distributed_solve_data_allocated = false;
2745  }
2746  if (Dist_global_solve_data_allocated)
2747  {
2748  superlu_dist_global_matrix(
2749  3,
2750  -1,
2751  ndof,
2752  0,
2753  0,
2754  0,
2755  0,
2756  0,
2757  Dist_nprow,
2758  Dist_npcol,
2759  doc,
2760  &Dist_solver_data_pt,
2761  &Dist_info,
2762  this->distribution_pt()->communicator_pt()->mpi_comm());
2763  Dist_global_solve_data_allocated = false;
2764  }
2765 
2766  Dist_solver_data_pt = 0;
2767 
2768  // Delete internal copy of the matrix
2769  delete[] Dist_value_pt;
2770  delete[] Dist_index_pt;
2771  delete[] Dist_start_pt;
2772  Dist_value_pt = 0;
2773  Dist_index_pt = 0;
2774  Dist_start_pt = 0;
2775 
2776  // and the distribution
2777  this->clear_distribution();
2778  }
2779 #endif
2780  }
void clear_distribution()
Definition: linear_algebra_distribution.h:522
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
Definition: linear_algebra_distribution.h:457
unsigned nrow() const
access function to the number of global rows.
Definition: linear_algebra_distribution.h:186

References oomph::DistributableLinearAlgebraObject::clear_distribution(), oomph::DistributableLinearAlgebraObject::distribution_pt(), Doc_stats, i, oomph::LinearAlgebraDistribution::nrow(), Serial_compressed_row_flag, Serial_f_factors, Serial_info, Serial_n_dof, oomph::superlu(), and anonymous_namespace{skew_symmetric_matrix3.cpp}::transpose().

Referenced by oomph::SuperLUPreconditioner::clean_up_memory(), disable_resolve(), factorise(), factorise_serial(), set_solver_type(), solve(), solve_transpose(), and ~SuperLUSolver().

◆ disable_doc_stats()

void oomph::SuperLUSolver::disable_doc_stats ( )
inline

Disable documentation of solver statistics.

610  {
611  Doc_stats = false;
612  }

References Doc_stats.

Referenced by oomph::SuperLUPreconditioner::disable_doc_stats(), and oomph::SuperLUPreconditioner::SuperLUPreconditioner().

◆ disable_resolve()

void oomph::SuperLUSolver::disable_resolve ( )
inlinevirtual

Overload disable resolve so that it cleans up memory too.

Reimplemented from oomph::LinearSolver.

550  {
552  clean_up_memory();
553  }
virtual void disable_resolve()
Definition: linear_solver.h:144

References clean_up_memory(), and oomph::LinearSolver::disable_resolve().

◆ enable_computation_of_gradient()

void oomph::SuperLUSolver::enable_computation_of_gradient ( )
inlinevirtual

function to enable the computation of the gradient

Reimplemented from oomph::LinearSolver.

541  {
542  Compute_gradient = true;
543  }
bool Compute_gradient
Definition: linear_solver.h:81

References oomph::LinearSolver::Compute_gradient.

◆ enable_doc_stats()

void oomph::SuperLUSolver::enable_doc_stats ( )
inline

Enable documentation of solver statistics.

604  {
605  Doc_stats = true;
606  }

References Doc_stats.

Referenced by oomph::SuperLUPreconditioner::enable_doc_stats().

◆ factorise()

void oomph::SuperLUSolver::factorise ( DoubleMatrixBase *const &  matrix_pt)

Do the factorisation stage Note: if Delete_matrix_data is true the function matrix_pt->clean_up_memory() will be used to wipe the matrix data.

LU decompose the matrix addressed by matrix_pt by using the SuperLU solver. The resulting matrix factors are stored internally.

1821  {
1822  // wipe memory
1823  this->clean_up_memory();
1824 
1825  // if we have mpi and the solver is distributed or default and nproc
1826  // gt 1
1827 #ifdef OOMPH_HAS_MPI
1828  DistributableLinearAlgebraObject* dist_matrix_pt =
1829  dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt);
1830  unsigned nproc = 1;
1831  if (dist_matrix_pt != 0)
1832  {
1833  nproc = dist_matrix_pt->distribution_pt()->communicator_pt()->nproc();
1834  }
1835  if (Solver_type == Distributed || (Solver_type == Default && nproc > 1 &&
1837  {
1838  // if the matrix is a distributed linear algebra object then use SuperLU
1839  // dist
1840  if (dist_matrix_pt != 0)
1841  {
1842  factorise_distributed(matrix_pt);
1843  Using_dist = true;
1844  }
1845  else
1846  {
1847  factorise_serial(matrix_pt);
1848  Using_dist = false;
1849  }
1850  }
1851  else
1852 #endif
1853  {
1854  factorise_serial(matrix_pt);
1855  Using_dist = false;
1856  }
1857  }
DistributableLinearAlgebraObject()
Default constructor - create a distribution.
Definition: linear_algebra_distribution.h:438
static bool mpi_has_been_initialised()
return true if MPI has been initialised
Definition: oomph_utilities.h:851
void factorise_serial(DoubleMatrixBase *const &matrix_pt)
factorise method for SuperLU (serial)
Definition: linear_solver.cc:2161

References clean_up_memory(), oomph::LinearAlgebraDistribution::communicator_pt(), Default, Distributed, oomph::DistributableLinearAlgebraObject::distribution_pt(), factorise_serial(), oomph::MPI_Helpers::mpi_has_been_initialised(), oomph::OomphCommunicator::nproc(), Solver_type, and Using_dist.

Referenced by oomph::SuperLUPreconditioner::setup(), solve(), and solve_transpose().

◆ factorise_serial()

void oomph::SuperLUSolver::factorise_serial ( DoubleMatrixBase *const &  matrix_pt)
private

factorise method for SuperLU (serial)

LU decompose the matrix addressed by matrix_pt by using the SuperLU solver. The resulting matrix factors are stored internally.

2162  {
2163 #ifdef PARANOID
2164  // PARANOID check that if the matrix is distributable then it should not be
2165  // then it should not be distributed
2166  if (dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt) != 0)
2167  {
2168  if (dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt)
2169  ->distributed())
2170  {
2171  std::ostringstream error_message_stream;
2172  error_message_stream << "The matrix must not be distributed.";
2173  throw OomphLibError(error_message_stream.str(),
2176  }
2177  }
2178 #endif
2179 
2180  // Find # of degrees of freedom (variables)
2181  int n = matrix_pt->nrow();
2182 
2183  // Check that we have a square matrix
2184 #ifdef PARANOID
2185  int m = matrix_pt->ncol();
2186  if (n != m)
2187  {
2188  std::ostringstream error_message_stream;
2189  error_message_stream << "Can only solve for square matrices\n"
2190  << "N, M " << n << " " << m << std::endl;
2191 
2192  throw OomphLibError(error_message_stream.str(),
2195  }
2196 #endif
2197 
2198  // Storage for the values, rows and column indices
2199  // required by SuplerLU
2200  double* value = 0;
2201  int *index = 0, *start = 0;
2202 
2203  // Integer used to represent compressed row or column format
2204  // Default compressed row
2205  int transpose = 0;
2206 
2207  // Number of non-zero entries in the matrix
2208  int nnz = 0;
2209 
2210  // Doc flag (convert to int for SuperLU)
2211  int doc = Doc_stats;
2212 
2213  // Is it a CR matrix
2214  if (dynamic_cast<CRDoubleMatrix*>(matrix_pt))
2215  {
2216  // Set the appropriate row flags
2218  transpose = 1;
2219  // Get a cast pointer to the matrix
2220  CRDoubleMatrix* CR_matrix_pt = dynamic_cast<CRDoubleMatrix*>(matrix_pt);
2221 
2222  // Now set the pointers to the interanally stored values
2223  // and indices
2224  nnz = CR_matrix_pt->nnz();
2225  value = CR_matrix_pt->value();
2226  index = CR_matrix_pt->column_index();
2227  start = CR_matrix_pt->row_start();
2228  }
2229  // Otherwise is it the compressed column version?
2230  else if (dynamic_cast<CCDoubleMatrix*>(matrix_pt))
2231  {
2232  // Set the compressed row flag to false
2234  // Get a cast pointer to the matrix
2235  CCDoubleMatrix* CC_matrix_pt = dynamic_cast<CCDoubleMatrix*>(matrix_pt);
2236 
2237  // Now set the pointers to the interanally stored values
2238  // and indices
2239  nnz = CC_matrix_pt->nnz();
2240  value = CC_matrix_pt->value();
2241  index = CC_matrix_pt->row_index();
2242  start = CC_matrix_pt->column_start();
2243  }
2244  // Otherwise throw and error
2245  else
2246  {
2247  throw OomphLibError("SuperLU only works with CR or CC Double matrices",
2250  }
2251 
2252  // Clean up any previous storage so that if this is called twice with
2253  // the same matrix, we don't get a memory leak
2254  clean_up_memory();
2255 
2256  // Perform the lu decompose phase (i=1)
2257  int i = 1;
2259  &n,
2260  &nnz,
2261  0,
2262  value,
2263  index,
2264  start,
2265  0,
2266  &n,
2267  &transpose,
2268  &doc,
2270  &Serial_info);
2271 
2272  // Throw an error if superLU returned an error status in info.
2273  if (Serial_info != 0)
2274  {
2275  std::ostringstream error_msg;
2276  error_msg << "SuperLU returned the error status code " << Serial_info
2277  << " . See the SuperLU documentation for what this means.";
2278  throw OomphLibError(
2280  }
2281 
2282 
2283  // Set the number of degrees of freedom in the linear system
2284  Serial_n_dof = n;
2285  }
bool distributed() const
distribution is serial or distributed
Definition: linear_algebra_distribution.h:493
int * m
Definition: level2_cplx_impl.h:294
squared absolute value
Definition: GlobalFunctions.h:87
void start(const unsigned &i)
(Re-)start i-th timer
Definition: oomph_utilities.cc:243

References clean_up_memory(), oomph::CRDoubleMatrix::column_index(), oomph::CCMatrix< T >::column_start(), oomph::DistributableLinearAlgebraObject::distributed(), Doc_stats, i, m, n, oomph::DoubleMatrixBase::ncol(), oomph::SparseMatrix< T, MATRIX_TYPE >::nnz(), oomph::CRDoubleMatrix::nnz(), oomph::DoubleMatrixBase::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::CCMatrix< T >::row_index(), oomph::CRDoubleMatrix::row_start(), Serial_compressed_row_flag, Serial_f_factors, Serial_info, Serial_n_dof, Serial_sign_of_determinant_of_matrix, oomph::CumulativeTimings::start(), oomph::superlu(), anonymous_namespace{skew_symmetric_matrix3.cpp}::transpose(), Eigen::value, oomph::SparseMatrix< T, MATRIX_TYPE >::value(), and oomph::CRDoubleMatrix::value().

Referenced by factorise().

◆ get_memory_usage_for_lu_factors()

double oomph::SuperLUSolver::get_memory_usage_for_lu_factors ( )

How much memory do the LU factors take up? In bytes.

How much memory do the LU factors take up? In bytes NOTE: This has been scraped from dQuerySpace(...) in dmemory.c in external_src/oomph_superlu_4.3

759  {
760  // If we're using the non-distributed version of SuperLU and the LU
761  // factors have also been computed
762  if ((Solver_type != Distributed) && (Serial_f_factors != 0))
763  {
765  }
766 #ifdef OOMPH_HAS_MPI
767  // If we're using SuperLU dist and the LU factors have been computed
768  if ((Solver_type == Distributed) && (Dist_solver_data_pt != 0))
769  {
770  return get_lu_factor_memory_usage_in_bytes_dist();
771  }
772 #endif
773  // If the factors haven't been computed we can't do anything
774  else
775  {
776  return 0.0;
777  }
778  } // End of get_memory_usage_for_lu_factors
double get_lu_factor_memory_usage_in_bytes()

References Distributed, oomph::get_lu_factor_memory_usage_in_bytes(), Serial_f_factors, and Solver_type.

Referenced by oomph::SuperLUPreconditioner::get_memory_usage_for_lu_factors(), and oomph::SuperLUPreconditioner::get_memory_usage_for_superlu().

◆ get_total_needed_memory()

double oomph::SuperLUSolver::get_total_needed_memory ( )

How much memory was allocated by SuperLU? In bytes.

How much memory was used in total? In bytes NOTE: This has been scraped from dQuerySpace(...) in dmemory.c in external_src/oomph_superlu_4.3

787  {
788  // If we're using the non-distributed version of SuperLU and the LU
789  // factors have also been computed
790  if ((Solver_type != Distributed) && (Serial_f_factors != 0))
791  {
793  }
794 #ifdef OOMPH_HAS_MPI
795  // If we're using SuperLU dist and the LU factors have been computed
796  if ((Solver_type == Distributed) && (Dist_solver_data_pt != 0))
797  {
798  return get_total_memory_usage_in_bytes_dist();
799  }
800 #endif
801  // If the factors haven't been computed we can't do anything
802  else
803  {
804  return 0.0;
805  }
806  } // End of get_total_needed_memory
double get_total_memory_usage_in_bytes()

References Distributed, oomph::get_total_memory_usage_in_bytes(), Serial_f_factors, and Solver_type.

Referenced by oomph::SuperLUPreconditioner::get_memory_usage_for_superlu(), oomph::SuperLUPreconditioner::get_total_memory_needed_for_superlu(), solve(), and solve_transpose().

◆ jacobian_setup_time()

double oomph::SuperLUSolver::jacobian_setup_time ( ) const
inlinevirtual

returns the time taken to assemble the jacobian matrix and residual vector

Reimplemented from oomph::LinearSolver.

617  {
618  return Jacobian_setup_time;
619  }
double Jacobian_setup_time
Jacobian setup time.
Definition: linear_solver.h:761

References Jacobian_setup_time.

◆ linear_solver_solution_time()

virtual double oomph::SuperLUSolver::linear_solver_solution_time ( ) const
inlinevirtual

return the time taken to solve the linear system (needs to be overloaded for each linear solver)

Reimplemented from oomph::LinearSolver.

624  {
625  return Solution_time;
626  }
double Solution_time
Solution time.
Definition: linear_solver.h:764

References Solution_time.

◆ operator=()

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

Broken assignment operator.

◆ resolve()

void oomph::SuperLUSolver::resolve ( const DoubleVector rhs,
DoubleVector result 
)
virtual

Resolve the system for a given RHS.

Resolve the system defined by the last assembled jacobian and the specified rhs vector if resolve has been enabled. Note: returns the global result Vector.

Reimplemented from oomph::LinearSolver.

1770  {
1771  // Store starting time for solve
1772  double t_start = TimingHelpers::timer();
1773 
1774  // backsub
1775  backsub(rhs, result);
1776 
1777  // Doc time for solve
1778  double t_end = TimingHelpers::timer();
1779  Solution_time = t_end - t_start;
1780  if (Doc_time)
1781  {
1782  oomph_info << "Time for SuperLUSolver solve (ndof=" << rhs.nrow() << "): "
1784  t_start)
1785  << std::endl;
1786  }
1787  }
bool Doc_time
Boolean flag that indicates whether the time taken.
Definition: linear_solver.h:77
void backsub(const DoubleVector &rhs, DoubleVector &result)
Definition: linear_solver.cc:2292
double timer()
returns the time in seconds after some point in past
Definition: oomph_utilities.cc:1295
std::string convert_secs_to_formatted_string(const double &time_in_sec)
Definition: oomph_utilities.cc:1316
OomphInfo oomph_info
Definition: oomph_definitions.cc:319

References backsub(), oomph::TimingHelpers::convert_secs_to_formatted_string(), oomph::LinearSolver::Doc_time, oomph::DistributableLinearAlgebraObject::nrow(), oomph::oomph_info, Solution_time, and oomph::TimingHelpers::timer().

Referenced by oomph::SuperLUPreconditioner::preconditioner_solve().

◆ resolve_transpose()

void oomph::SuperLUSolver::resolve_transpose ( const DoubleVector rhs,
DoubleVector result 
)
virtual

Resolve the (transposed) system for a given RHS.

Resolve the (transposed) system defined by the last assembled Jacobian and the specified rhs vector if resolve has been enabled.

Reimplemented from oomph::LinearSolver.

1795  {
1796  // Store starting time for solve
1797  double t_start = TimingHelpers::timer();
1798 
1799  // Backsub (but solve the transposed system)
1800  backsub_transpose(rhs, result);
1801 
1802  // Doc time for solve
1803  double t_end = TimingHelpers::timer();
1804  Solution_time = t_end - t_start;
1805  if (Doc_time)
1806  {
1807  oomph_info << "Time for SuperLUSolver solve (ndof=" << rhs.nrow() << "): "
1809  t_start)
1810  << std::endl;
1811  }
1812  }
void backsub_transpose(const DoubleVector &rhs, DoubleVector &result)
Definition: linear_solver.cc:2312

References backsub_transpose(), oomph::TimingHelpers::convert_secs_to_formatted_string(), oomph::LinearSolver::Doc_time, oomph::DistributableLinearAlgebraObject::nrow(), oomph::oomph_info, Solution_time, and oomph::TimingHelpers::timer().

Referenced by oomph::SuperLUPreconditioner::preconditioner_solve_transpose().

◆ set_solver_type()

void oomph::SuperLUSolver::set_solver_type ( const Type t)
inline

Specify the solve type. Either default, serial or distributed. See enum SuperLU_solver_type for more details.

647  {
648  this->clean_up_memory();
649  Solver_type = t;
650  }
t
Definition: plotPSD.py:36

References clean_up_memory(), Solver_type, and plotPSD::t.

◆ solve() [1/2]

void oomph::SuperLUSolver::solve ( DoubleMatrixBase *const &  matrix_pt,
const DoubleVector rhs,
DoubleVector result 
)
virtual

Linear-algebra-type solver: Takes pointer to a matrix and rhs vector and returns the solution of the linear system. The function returns the global result Vector. Note: if Delete_matrix_data is true the function matrix_pt->clean_up_memory() will be used to wipe the matrix data.

Linear-algebra-type solver: Takes pointer to a matrix and rhs vector and returns the solution of the linear system. Problem pointer defaults to NULL and can be omitted. The function returns the global result Vector. Note: if Delete_matrix_data is true the function matrix_pt->clean_up_memory() will be used to wipe the matrix data.

Reimplemented from oomph::LinearSolver.

1077  {
1078  // Initialise timer
1079  double t_start = TimingHelpers::timer();
1080 
1081  // Pointer used in various places
1082  CRDoubleMatrix* cr_pt = 0;
1083 
1084 
1085 #ifdef PARANOID
1086  // check that the rhs vector is setup
1087  if (!rhs.built())
1088  {
1089  std::ostringstream error_message_stream;
1090  error_message_stream << "The vectors rhs must be setup";
1091  throw OomphLibError(error_message_stream.str(),
1094  }
1095 
1096  // check that the matrix is square
1097  if (matrix_pt->nrow() != matrix_pt->ncol())
1098  {
1099  std::ostringstream error_message_stream;
1100  error_message_stream << "The matrix at matrix_pt must be square.";
1101  throw OomphLibError(error_message_stream.str(),
1104  }
1105 
1106  // check that the matrix has some entries, and so has a values_pt that
1107  // makes sense (only for CR because CC is never used I think dense
1108  // matrices will be safe since they don't use a values pointer).
1109  cr_pt = dynamic_cast<CRDoubleMatrix*>(matrix_pt);
1110  if (cr_pt != 0)
1111  {
1112  if (cr_pt->nnz() == 0)
1113  {
1114  std::ostringstream error_message_stream;
1115  error_message_stream
1116  << "Attempted to call SuperLu on a CRDoubleMatrix with no entries, "
1117  << "SuperLU would segfault (because the values array pt is "
1118  << "uninitialised or null).";
1119  throw OomphLibError(error_message_stream.str(),
1122  }
1123  }
1124 
1125  // check that the matrix and the rhs vector have the same nrow()
1126  if (matrix_pt->nrow() != rhs.nrow())
1127  {
1128  std::ostringstream error_message_stream;
1129  error_message_stream
1130  << "The matrix and the rhs vector must have the same number of rows.";
1131  throw OomphLibError(error_message_stream.str(),
1134  }
1135 
1136  // if the matrix is distributable then should have the same distribution
1137  // as the rhs vector
1138  DistributableLinearAlgebraObject* dist_matrix_pt =
1139  dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt);
1140  if (dist_matrix_pt != 0)
1141  {
1142  if (!(*dist_matrix_pt->distribution_pt() == *rhs.distribution_pt()))
1143  {
1144  std::ostringstream error_message_stream;
1145  error_message_stream
1146  << "The matrix matrix_pt must have the same distribution as the "
1147  << "rhs vector.";
1148  throw OomphLibError(error_message_stream.str(),
1151  }
1152  }
1153  // if the matrix is not distributable then it the rhs vector should not be
1154  // distributed
1155  else
1156  {
1157  if (rhs.distribution_pt()->distributed())
1158  {
1159  std::ostringstream error_message_stream;
1160  error_message_stream
1161  << "The matrix (matrix_pt) is not distributable and therefore the rhs"
1162  << " vector must not be distributed";
1163  throw OomphLibError(error_message_stream.str(),
1166  }
1167  }
1168  // if the result vector is setup then check it has the same distribution
1169  // as the rhs
1170  if (result.built())
1171  {
1172  if (!(*result.distribution_pt() == *rhs.distribution_pt()))
1173  {
1174  std::ostringstream error_message_stream;
1175  error_message_stream
1176  << "The result vector distribution has been setup; it must have the "
1177  << "same distribution as the rhs vector.";
1178  throw OomphLibError(error_message_stream.str(),
1181  }
1182  }
1183 #endif
1184 
1185  // set the distribution
1186  if (dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt))
1187  {
1188  // the solver has the same distribution as the matrix if possible
1189  this->build_distribution(
1190  dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt)
1191  ->distribution_pt());
1192  }
1193  else
1194  {
1195  // the solver has the same distribution as the RHS
1196  this->build_distribution(rhs.distribution_pt());
1197  }
1198 
1199  // Doc time for solve
1200  double t_factorise_start = TimingHelpers::timer();
1201 
1202  // Factorise the matrix
1203  factorise(matrix_pt);
1204 
1205  // Doc the end time
1206  double t_factorise_end = TimingHelpers::timer();
1207 
1208  // How long did the factorisation take?
1209  double factorise_time = t_factorise_end - t_factorise_start;
1210 
1211  // Try and upcast the matrix to a CRDoubleMatrix
1212  // CRDoubleMatrix*
1213  cr_pt = dynamic_cast<CRDoubleMatrix*>(matrix_pt);
1214 
1215  // If the input matrix is a CRDoubleMatrix
1216  if (cr_pt != 0)
1217  {
1218  // ...and actually has an entry
1219  if (cr_pt->nnz() != 0)
1220  {
1221  // Find out how many rows there are in the global Jacobian
1222  unsigned n_row = cr_pt->nrow();
1223 
1224  // And how many non-zeros there are in the global Jacobian
1225  unsigned n_nnz = cr_pt->nnz();
1226 
1227  // Get the memory usage (in bytes) for the global Jacobian storage
1228  double memory_usage_for_jacobian =
1229  ((2 * ((n_row + 1) * sizeof(int))) +
1230  (n_nnz * (sizeof(int) + sizeof(double))));
1231 
1232  // Get the memory usage (in bytes) for storage of the LU factors in
1233  // SuperLU
1234  double memory_usage_for_lu_storage = get_total_needed_memory();
1235 
1236  // Get the memory usage (in bytes) for storage of the LU factors in
1237  // SuperLU
1238  double total_memory_usage =
1239  memory_usage_for_jacobian + memory_usage_for_lu_storage;
1240 
1241  // How much memory have we used in the subsidiary preconditioners?
1242  oomph_info << "\nMemory statistics:"
1243  << "\n - Memory used to store the Jacobian (MB) : "
1244  << memory_usage_for_jacobian / 1.0e+06
1245  << "\n - Memory used to store the LU factors (MB) : "
1246  << memory_usage_for_lu_storage / 1.0e+06
1247  << "\n - Total memory used for matrix storage (MB): "
1248  << total_memory_usage / 1.0e+06 << "\n"
1249  << std::endl;
1250  }
1251  } // if (cr_pt!=0)
1252 
1253  // Doc the start time
1254  double t_backsub_start = TimingHelpers::timer();
1255 
1256  // Now do the back solve
1257  backsub(rhs, result);
1258 
1259  // Doc the end time
1260  double t_backsub_end = TimingHelpers::timer();
1261 
1262  // How long did the back substitution take?
1263  double backsub_time = t_backsub_end - t_backsub_start;
1264 
1265  // Doc time for solve
1266  double t_end = TimingHelpers::timer();
1267  Solution_time = t_end - t_start;
1268  if (Doc_time)
1269  {
1270  oomph_info
1271  << "Time for LU factorisation : "
1273  << "\nTime for back-substitution: "
1275  << "\nTime for SuperLUSolver solve (ndof=" << matrix_pt->nrow() << "): "
1277  << std::endl;
1278  }
1279 
1280  // If we are not storing the solver data for resolves, delete it
1281  if (!Enable_resolve)
1282  {
1283  clean_up_memory();
1284  }
1285  }
void build_distribution(const LinearAlgebraDistribution *const dist_pt)
Definition: linear_algebra_distribution.h:507
bool Enable_resolve
Definition: linear_solver.h:73
void factorise(DoubleMatrixBase *const &matrix_pt)
Definition: linear_solver.cc:1820
double get_total_needed_memory()
How much memory was allocated by SuperLU? In bytes.
Definition: linear_solver.cc:786
return int(ret)+1

References backsub(), oomph::DistributableLinearAlgebraObject::build_distribution(), oomph::DoubleVector::built(), clean_up_memory(), oomph::TimingHelpers::convert_secs_to_formatted_string(), oomph::LinearAlgebraDistribution::distributed(), oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::LinearSolver::Doc_time, oomph::LinearSolver::Enable_resolve, factorise(), get_total_needed_memory(), int(), oomph::DoubleMatrixBase::ncol(), oomph::CRDoubleMatrix::nnz(), oomph::DistributableLinearAlgebraObject::nrow(), oomph::CRDoubleMatrix::nrow(), oomph::DoubleMatrixBase::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, Solution_time, and oomph::TimingHelpers::timer().

◆ solve() [2/2]

void oomph::SuperLUSolver::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.

815  {
816  // wipe memory
817  this->clean_up_memory();
818 
819 #ifdef OOMPH_HAS_MPI
820  // USING SUPERLU DIST
822  if (Solver_type == Distributed ||
823  (Solver_type == Default && problem_pt->communicator_pt()->nproc() > 1))
824  {
825  // init the timers
826  double t_start = TimingHelpers::timer();
827 
828  // number of dofs
829  unsigned n_dof = problem_pt->ndof();
830 
831  // set the distribution
832  LinearAlgebraDistribution dist(
833  problem_pt->communicator_pt(), n_dof, !Dist_use_global_solver);
834  this->build_distribution(dist);
835 
836  // Take a copy of Delete_matrix_data
837  bool copy_of_Delete_matrix_data = Dist_delete_matrix_data;
838 
839  // Set Delete_matrix to true
840  Dist_delete_matrix_data = true;
841 
842  // Use the distributed version of SuperLU_DIST?
843  if (!Dist_use_global_solver)
844  {
845  // Initialise timer
846  double t_start = TimingHelpers::timer();
847 
848  // Storage for the residuals vector
849  DoubleVector residuals(this->distribution_pt(), 0.0);
850 
851  // Get the sparse jacobian and residuals of the problem
852  CRDoubleMatrix jacobian(this->distribution_pt());
853  problem_pt->get_jacobian(residuals, jacobian);
854 
855  // Doc time for setup
856  double t_end = TimingHelpers::timer();
857  Jacobian_setup_time = t_end - t_start;
858  if (Doc_time)
859  {
860  oomph_info << "Time to set up CRDoubleMatrix Jacobian : "
863  << std::endl;
864  }
865 
866  // Now call the linear algebra solve, if desired
867  if (!Suppress_solve)
868  {
869  // If the distribution of the result has been build and
870  // does not match that of
871  // the solver then redistribute before the solve and return
872  // to the incoming distribution afterwards.
873  if ((result.built()) &&
874  (!(*result.distribution_pt() == *this->distribution_pt())))
875  {
876  LinearAlgebraDistribution temp_global_dist(
877  result.distribution_pt());
878  result.build(this->distribution_pt(), 0.0);
879  solve(&jacobian, residuals, result);
880  result.redistribute(&temp_global_dist);
881  }
882  else
883  {
884  solve(&jacobian, residuals, result);
885  }
886  }
887  }
888  // Otherwise its the global solve version
889  else
890  {
891  // Storage for the residuals vector
892  // A non-distriubted residuals vector
893  LinearAlgebraDistribution dist(
894  problem_pt->communicator_pt(), problem_pt->ndof(), false);
895  DoubleVector residuals(&dist, 0.0);
896  CRDoubleMatrix jacobian(&dist);
897 
898  // Get the sparse jacobian and residuals of the problem
899  problem_pt->get_jacobian(residuals, jacobian);
900 
901  // Doc time for setup
902  double t_end = TimingHelpers::timer();
903  Jacobian_setup_time = t_end - t_start;
904  if (Doc_time)
905  {
906  oomph_info << "Time to set up CR Jacobian : "
909  << std::endl;
910  }
911 
912  // Now call the linear algebra solve, if desired
913  if (!Suppress_solve)
914  {
915  // If the result distribution has been built and
916  // does not match the global distribution
917  // the redistribute before the solve and then return to the
918  // distributed version afterwards
919  if ((result.built()) && (!(*result.distribution_pt() == dist)))
920  {
921  LinearAlgebraDistribution temp_global_dist(
922  result.distribution_pt());
923  result.build(&dist, 0.0);
924  solve(&jacobian, residuals, result);
925  result.redistribute(&temp_global_dist);
926  }
927  else
928  {
929  solve(&jacobian, residuals, result);
930  }
931  }
932  }
933  // Set Delete_matrix back to original value
934  Dist_delete_matrix_data = copy_of_Delete_matrix_data;
935  }
936 
937  // OTHERWISE WE ARE USING SUPERLU (SERIAL)
939  else
940 #endif
941  {
942  // set the solver distribution
943  LinearAlgebraDistribution dist(
944  problem_pt->communicator_pt(), problem_pt->ndof(), false);
945  this->build_distribution(dist);
946 
947  // Allocate storage for the residuals vector
948  DoubleVector residuals(dist, 0.0);
949 
950  // Use the compressed row version?
952  {
953  // Initialise timer
954  double t_start = TimingHelpers::timer();
955 
956  // Get the sparse jacobian and residuals of the problem
957  CRDoubleMatrix CR_jacobian(this->distribution_pt());
958  problem_pt->get_jacobian(residuals, CR_jacobian);
959 
960  // If we want to compute the gradient for the globally convergent
961  // Newton method, then do it here
962  if (Compute_gradient)
963  {
964  // Compute it
965  CR_jacobian.multiply_transpose(residuals,
967  // Set the flag
969  }
970 
971  // Doc time for setup
972  double t_end = TimingHelpers::timer();
973  Jacobian_setup_time = t_end - t_start;
974  if (Doc_time)
975  {
976  oomph_info << std::endl
977  << "Time to set up CRDoubleMatrix Jacobian : "
980  << std::endl;
981  }
982 
983  // Now call the linear algebra solve, if desired
984  if (!Suppress_solve)
985  {
986  // If the result vector is built and distributed
987  // then need to redistribute into the same form as the
988  // RHS (non-distributed)
989  if ((result.built()) &&
990  (!(*result.distribution_pt() == *this->distribution_pt())))
991  {
992  LinearAlgebraDistribution temp_global_dist(
993  result.distribution_pt());
994  result.build(this->distribution_pt(), 0.0);
995  solve(&CR_jacobian, residuals, result);
996  result.redistribute(&temp_global_dist);
997  }
998  // Otherwise just solve
999  else
1000  {
1001  solve(&CR_jacobian, residuals, result);
1002  }
1003  }
1004  }
1005  // Otherwise its the compressed column version
1006  else
1007  {
1008  // Initialise timer
1009  double t_start = TimingHelpers::timer();
1010 
1011  // Get the sparse jacobian and residuals of the problem
1012  CCDoubleMatrix CC_jacobian;
1013  problem_pt->get_jacobian(residuals, CC_jacobian);
1014 
1015  // If we want to compute the gradient for the globally convergent
1016  // Newton method, then do it here
1017  if (Compute_gradient)
1018  {
1019  // Compute it
1020  CC_jacobian.multiply_transpose(residuals,
1022  // Set the flag
1024  }
1025 
1026  // Doc time for setup
1027  double t_end = TimingHelpers::timer();
1028  Jacobian_setup_time = t_end - t_start;
1029  if (Doc_time)
1030  {
1031  oomph_info << "\nTime to set up CCDoubleMatrix Jacobian: "
1034  << std::endl;
1035  }
1036 
1037  // Now call the linear algebra solve, if desired
1038  if (!Suppress_solve)
1039  {
1040  // If the result vector is built and distributed
1041  // then need to redistribute into the same form as the
1042  // RHS
1043  if ((result.built()) &&
1044  (!(*result.distribution_pt() == *this->distribution_pt())))
1045  {
1046  LinearAlgebraDistribution temp_global_dist(
1047  result.distribution_pt());
1048  result.build(this->distribution_pt(), 0.0);
1049  solve(&CC_jacobian, residuals, result);
1050  result.redistribute(&temp_global_dist);
1051  }
1052  // Otherwise just solve
1053  else
1054  {
1055  solve(&CC_jacobian, residuals, result);
1056  }
1057  }
1058  }
1059 
1060  // Set the sign of the jacobian
1061  //(this is computed in the LU decomposition phase)
1062  problem_pt->sign_of_jacobian() = Serial_sign_of_determinant_of_matrix;
1063  }
1064  }
std::vector< double > DoubleVector
loads clump configuration
Definition: ClumpInput.h:26
bool Gradient_has_been_computed
flag that indicates whether the gradient was computed or not
Definition: linear_solver.h:84
DoubleVector Gradient_for_glob_conv_newton_solve
Definition: linear_solver.h:88
void solve(Problem *const &problem_pt, DoubleVector &result)
Definition: linear_solver.cc:814

References oomph::DoubleVector::build(), oomph::DistributableLinearAlgebraObject::build_distribution(), oomph::DoubleVector::built(), clean_up_memory(), oomph::Problem::communicator_pt(), oomph::LinearSolver::Compute_gradient, oomph::TimingHelpers::convert_secs_to_formatted_string(), Default, Distributed, oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::LinearSolver::Doc_time, oomph::Problem::get_jacobian(), oomph::LinearSolver::Gradient_for_glob_conv_newton_solve, oomph::LinearSolver::Gradient_has_been_computed, Jacobian_setup_time, oomph::CRDoubleMatrix::multiply_transpose(), oomph::CCDoubleMatrix::multiply_transpose(), oomph::Problem::ndof(), oomph::OomphCommunicator::nproc(), oomph::oomph_info, oomph::DoubleVector::redistribute(), Serial_compressed_row_flag, Serial_sign_of_determinant_of_matrix, oomph::Problem::sign_of_jacobian(), Solver_type, Suppress_solve, and oomph::TimingHelpers::timer().

◆ solve_transpose() [1/2]

void oomph::SuperLUSolver::solve_transpose ( DoubleMatrixBase *const &  matrix_pt,
const DoubleVector rhs,
DoubleVector result 
)
virtual

Linear-algebra-type solver: Takes pointer to a matrix and rhs vector and returns the solution of the linear system. The function returns the global result Vector. Note: if Delete_matrix_data is true the function matrix_pt->clean_up_memory() will be used to wipe the matrix data.

Linear-algebra-type solver: Takes pointer to a matrix and rhs vector and returns the solution of the linear system. Problem pointer defaults to NULL and can be omitted. The function returns the global result Vector. Note: if Delete_matrix_data is true the function matrix_pt->clean_up_memory() will be used to wipe the matrix data.

Reimplemented from oomph::LinearSolver.

1557  {
1558  // Initialise timer
1559  double t_start = TimingHelpers::timer();
1560 
1561  // Pointer used in various places
1562  CRDoubleMatrix* cr_pt = 0;
1563 
1564 #ifdef PARANOID
1565  // check that the rhs vector is setup
1566  if (!rhs.built())
1567  {
1568  std::ostringstream error_message_stream;
1569  error_message_stream << "The vectors rhs must be setup";
1570  throw OomphLibError(error_message_stream.str(),
1573  }
1574 
1575  // check that the matrix is square
1576  if (matrix_pt->nrow() != matrix_pt->ncol())
1577  {
1578  std::ostringstream error_message_stream;
1579  error_message_stream << "The matrix at matrix_pt must be square.";
1580  throw OomphLibError(error_message_stream.str(),
1583  }
1584 
1585  // check that the matrix has some entries, and so has a values_pt that
1586  // makes sense (only for CR because CC is never used I think dense
1587  // matrices will be safe since they don't use a values pointer).
1588  cr_pt = dynamic_cast<CRDoubleMatrix*>(matrix_pt);
1589  if (cr_pt != 0)
1590  {
1591  if (cr_pt->nnz() == 0)
1592  {
1593  std::ostringstream error_message_stream;
1594  error_message_stream
1595  << "Attempted to call SuperLu on a CRDoubleMatrix with no entries, "
1596  << "SuperLU would segfault (because the values array pt is "
1597  << "uninitialised or null).";
1598  throw OomphLibError(error_message_stream.str(),
1601  }
1602  }
1603 
1604  // check that the matrix and the rhs vector have the same nrow()
1605  if (matrix_pt->nrow() != rhs.nrow())
1606  {
1607  std::ostringstream error_message_stream;
1608  error_message_stream
1609  << "The matrix and the rhs vector must have the same number of rows.";
1610  throw OomphLibError(error_message_stream.str(),
1613  }
1614 
1615  // if the matrix is distributable then should have the same distribution
1616  // as the rhs vector
1617  DistributableLinearAlgebraObject* dist_matrix_pt =
1618  dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt);
1619  if (dist_matrix_pt != 0)
1620  {
1621  if (!(*dist_matrix_pt->distribution_pt() == *rhs.distribution_pt()))
1622  {
1623  std::ostringstream error_message_stream;
1624  error_message_stream
1625  << "The matrix matrix_pt must have the same distribution as the "
1626  << "rhs vector.";
1627  throw OomphLibError(error_message_stream.str(),
1630  }
1631  }
1632  // if the matrix is not distributable then it the rhs vector should not be
1633  // distributed
1634  else
1635  {
1636  if (rhs.distribution_pt()->distributed())
1637  {
1638  std::ostringstream error_message_stream;
1639  error_message_stream
1640  << "The matrix (matrix_pt) is not distributable and therefore the rhs"
1641  << " vector must not be distributed";
1642  throw OomphLibError(error_message_stream.str(),
1645  }
1646  }
1647  // if the result vector is setup then check it has the same distribution
1648  // as the rhs
1649  if (result.built())
1650  {
1651  if (!(*result.distribution_pt() == *rhs.distribution_pt()))
1652  {
1653  std::ostringstream error_message_stream;
1654  error_message_stream
1655  << "The result vector distribution has been setup; it must have the "
1656  << "same distribution as the rhs vector.";
1657  throw OomphLibError(error_message_stream.str(),
1660  }
1661  }
1662 #endif
1663 
1664  // set the distribution
1665  if (dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt))
1666  {
1667  // the solver has the same distribution as the matrix if possible
1668  this->build_distribution(
1669  dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt)
1670  ->distribution_pt());
1671  }
1672  else
1673  {
1674  // the solver has the same distribution as the RHS
1675  this->build_distribution(rhs.distribution_pt());
1676  }
1677 
1678  // Doc time for solve
1679  double t_factorise_start = TimingHelpers::timer();
1680 
1681  // Factorise the matrix
1682  factorise(matrix_pt);
1683 
1684  // Doc the end time
1685  double t_factorise_end = TimingHelpers::timer();
1686 
1687  // How long did the factorisation take?
1688  double factorise_time = t_factorise_end - t_factorise_start;
1689 
1690  // Try and upcast the matrix to a CRDoubleMatrix
1691  // CRDoubleMatrix*
1692  cr_pt = dynamic_cast<CRDoubleMatrix*>(matrix_pt);
1693 
1694  // If the input matrix is a CRDoubleMatrix
1695  if (cr_pt != 0)
1696  {
1697  // ...and actually has an entry
1698  if (cr_pt->nnz() != 0)
1699  {
1700  // Find out how many rows there are in the global Jacobian
1701  unsigned n_row = cr_pt->nrow();
1702 
1703  // And how many non-zeros there are in the global Jacobian
1704  unsigned n_nnz = cr_pt->nnz();
1705 
1706  // Get the memory usage (in bytes) for the global Jacobian storage
1707  double memory_usage_for_jacobian =
1708  ((2 * ((n_row + 1) * sizeof(int))) +
1709  (n_nnz * (sizeof(int) + sizeof(double))));
1710 
1711  // Get the memory usage (in bytes) for storage of the LU factors in
1712  // SuperLU
1713  double memory_usage_for_lu_storage = get_total_needed_memory();
1714 
1715  // Get the memory usage (in bytes) for storage of the LU factors in
1716  // SuperLU
1717  double total_memory_usage =
1718  memory_usage_for_jacobian + memory_usage_for_lu_storage;
1719 
1720  // How much memory have we used in the subsidiary preconditioners?
1721  oomph_info << "\nMemory statistics:"
1722  << "\n - Memory used to store the Jacobian (MB): "
1723  << memory_usage_for_jacobian / 1.0e+06
1724  << "\n - Memory used to store the LU factors (MB): "
1725  << memory_usage_for_lu_storage / 1.0e+06
1726  << "\n - Total memory used for matrix storage (MB): "
1727  << total_memory_usage / 1.0e+06 << "\n"
1728  << std::endl;
1729  }
1730  } // if (cr_pt!=0)
1731 
1732  // Doc the start time
1733  double t_backsub_start = TimingHelpers::timer();
1734 
1735  // Now do the back solve
1736  backsub_transpose(rhs, result);
1737 
1738  // Doc the end time
1739  double t_backsub_end = TimingHelpers::timer();
1740 
1741  // How long did the back substitution take?
1742  double backsub_time = t_backsub_end - t_backsub_start;
1743 
1744  // Doc time for solve
1745  double t_end = TimingHelpers::timer();
1746  Solution_time = t_end - t_start;
1747  if (Doc_time)
1748  {
1749  oomph_info
1750  << "Time for LU factorisation : "
1752  << "\nTime for back-substitution: "
1754  << "\nTime for SuperLUSolver solve (ndof=" << matrix_pt->nrow() << "): "
1756  << std::endl;
1757  }
1758 
1759  // If we are not storing the solver data for resolves, delete it
1760  if (!Enable_resolve)
1761  {
1762  clean_up_memory();
1763  }
1764  } // End of solve_transpose

References backsub_transpose(), oomph::DistributableLinearAlgebraObject::build_distribution(), oomph::DoubleVector::built(), clean_up_memory(), oomph::TimingHelpers::convert_secs_to_formatted_string(), oomph::LinearAlgebraDistribution::distributed(), oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::LinearSolver::Doc_time, oomph::LinearSolver::Enable_resolve, factorise(), get_total_needed_memory(), int(), oomph::DoubleMatrixBase::ncol(), oomph::CRDoubleMatrix::nnz(), oomph::DistributableLinearAlgebraObject::nrow(), oomph::CRDoubleMatrix::nrow(), oomph::DoubleMatrixBase::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, Solution_time, and oomph::TimingHelpers::timer().

◆ solve_transpose() [2/2]

void oomph::SuperLUSolver::solve_transpose ( 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.

Reimplemented from oomph::LinearSolver.

1295  {
1296  // wipe memory
1297  this->clean_up_memory();
1298 
1299 #ifdef OOMPH_HAS_MPI
1300  // USING SUPERLU DIST
1302  if (Solver_type == Distributed ||
1303  (Solver_type == Default && problem_pt->communicator_pt()->nproc() > 1))
1304  {
1305  // init the timers
1306  double t_start = TimingHelpers::timer();
1307 
1308  // number of dofs
1309  unsigned n_dof = problem_pt->ndof();
1310 
1311  // set the distribution
1312  LinearAlgebraDistribution dist(
1313  problem_pt->communicator_pt(), n_dof, !Dist_use_global_solver);
1314  this->build_distribution(dist);
1315 
1316  // Take a copy of Delete_matrix_data
1317  bool copy_of_Delete_matrix_data = Dist_delete_matrix_data;
1318 
1319  // Set Delete_matrix to true
1320  Dist_delete_matrix_data = true;
1321 
1322  // Use the distributed version of SuperLU_DIST?
1323  if (!Dist_use_global_solver)
1324  {
1325  // Initialise timer
1326  double t_start = TimingHelpers::timer();
1327 
1328  // Storage for the residuals vector
1329  DoubleVector residuals(this->distribution_pt(), 0.0);
1330 
1331  // Get the sparse jacobian and residuals of the problem
1332  CRDoubleMatrix jacobian(this->distribution_pt());
1333  problem_pt->get_jacobian(residuals, jacobian);
1334 
1335  // Doc time for setup
1336  double t_end = TimingHelpers::timer();
1337  Jacobian_setup_time = t_end - t_start;
1338  if (Doc_time)
1339  {
1340  oomph_info << "Time to set up CRDoubleMatrix Jacobian : "
1343  << std::endl;
1344  }
1345 
1346  // Now call the linear algebra solve, if desired
1347  if (!Suppress_solve)
1348  {
1349  // If the distribution of the result has been build and
1350  // does not match that of
1351  // the solver then redistribute before the solve and return
1352  // to the incoming distribution afterwards.
1353  if ((result.built()) &&
1354  (!(*result.distribution_pt() == *this->distribution_pt())))
1355  {
1356  LinearAlgebraDistribution temp_global_dist(
1357  result.distribution_pt());
1358  result.build(this->distribution_pt(), 0.0);
1359  solve_transpose(&jacobian, residuals, result);
1360  result.redistribute(&temp_global_dist);
1361  }
1362  else
1363  {
1364  solve_transpose(&jacobian, residuals, result);
1365  }
1366  }
1367  }
1368  // Otherwise its the global solve version
1369  else
1370  {
1371  // Storage for the residuals vector
1372  // A non-distriubted residuals vector
1373  LinearAlgebraDistribution dist(
1374  problem_pt->communicator_pt(), problem_pt->ndof(), false);
1375  DoubleVector residuals(&dist, 0.0);
1376  CRDoubleMatrix jacobian(&dist);
1377 
1378  // Get the sparse jacobian and residuals of the problem
1379  problem_pt->get_jacobian(residuals, jacobian);
1380 
1381  // Doc time for setup
1382  double t_end = TimingHelpers::timer();
1383  Jacobian_setup_time = t_end - t_start;
1384  if (Doc_time)
1385  {
1386  oomph_info << "Time to set up CR Jacobian : "
1389  << std::endl;
1390  }
1391 
1392  // Now call the linear algebra solve, if desired
1393  if (!Suppress_solve)
1394  {
1395  // If the result distribution has been built and
1396  // does not match the global distribution
1397  // the redistribute before the solve and then return to the
1398  // distributed version afterwards
1399  if ((result.built()) && (!(*result.distribution_pt() == dist)))
1400  {
1401  LinearAlgebraDistribution temp_global_dist(
1402  result.distribution_pt());
1403  result.build(&dist, 0.0);
1404  solve_transpose(&jacobian, residuals, result);
1405  result.redistribute(&temp_global_dist);
1406  }
1407  else
1408  {
1409  solve_transpose(&jacobian, residuals, result);
1410  }
1411  }
1412  }
1413  // Set Delete_matrix back to original value
1414  Dist_delete_matrix_data = copy_of_Delete_matrix_data;
1415  }
1416 
1417  // OTHERWISE WE ARE USING SUPERLU (SERIAL)
1419  else
1420 #endif
1421  {
1422  // set the solver distribution
1423  LinearAlgebraDistribution dist(
1424  problem_pt->communicator_pt(), problem_pt->ndof(), false);
1425  this->build_distribution(dist);
1426 
1427  // Allocate storage for the residuals vector
1428  DoubleVector residuals(dist, 0.0);
1429 
1430  // Use the compressed row version?
1432  {
1433  // Initialise timer
1434  double t_start = TimingHelpers::timer();
1435 
1436  // Get the sparse jacobian and residuals of the problem
1437  CRDoubleMatrix CR_jacobian(this->distribution_pt());
1438  problem_pt->get_jacobian(residuals, CR_jacobian);
1439 
1440  // If we want to compute the gradient for the globally convergent
1441  // Newton method, then do it here
1442  if (Compute_gradient)
1443  {
1444  // Compute it
1445  CR_jacobian.multiply_transpose(residuals,
1447  // Set the flag
1449  }
1450 
1451  // Doc time for setup
1452  double t_end = TimingHelpers::timer();
1453  Jacobian_setup_time = t_end - t_start;
1454  if (Doc_time)
1455  {
1456  oomph_info << std::endl
1457  << "Time to set up CRDoubleMatrix Jacobian: "
1460  << std::endl;
1461  }
1462 
1463  // Now call the linear algebra solve, if desired
1464  if (!Suppress_solve)
1465  {
1466  // If the result vector is built and distributed
1467  // then need to redistribute into the same form as the
1468  // RHS (non-distributed)
1469  if ((result.built()) &&
1470  (!(*result.distribution_pt() == *this->distribution_pt())))
1471  {
1472  LinearAlgebraDistribution temp_global_dist(
1473  result.distribution_pt());
1474  result.build(this->distribution_pt(), 0.0);
1475  solve_transpose(&CR_jacobian, residuals, result);
1476  result.redistribute(&temp_global_dist);
1477  }
1478  // Otherwise just solve
1479  else
1480  {
1481  solve_transpose(&CR_jacobian, residuals, result);
1482  }
1483  }
1484  }
1485  // Otherwise its the compressed column version
1486  else
1487  {
1488  // Initialise timer
1489  double t_start = TimingHelpers::timer();
1490 
1491  // Get the sparse jacobian and residuals of the problem
1492  CCDoubleMatrix CC_jacobian;
1493  problem_pt->get_jacobian(residuals, CC_jacobian);
1494 
1495  // If we want to compute the gradient for the globally convergent
1496  // Newton method, then do it here
1497  if (Compute_gradient)
1498  {
1499  // Compute it
1500  CC_jacobian.multiply_transpose(residuals,
1502  // Set the flag
1504  }
1505 
1506  // Doc time for setup
1507  double t_end = TimingHelpers::timer();
1508  Jacobian_setup_time = t_end - t_start;
1509  if (Doc_time)
1510  {
1511  oomph_info << "\nTime to set up CCDoubleMatrix Jacobian: "
1514  << std::endl;
1515  }
1516 
1517  // Now call the linear algebra solve, if desired
1518  if (!Suppress_solve)
1519  {
1520  // If the result vector is built and distributed
1521  // then need to redistribute into the same form as the
1522  // RHS
1523  if ((result.built()) &&
1524  (!(*result.distribution_pt() == *this->distribution_pt())))
1525  {
1526  LinearAlgebraDistribution temp_global_dist(
1527  result.distribution_pt());
1528  result.build(this->distribution_pt(), 0.0);
1529  solve_transpose(&CC_jacobian, residuals, result);
1530  result.redistribute(&temp_global_dist);
1531  }
1532  // Otherwise just solve
1533  else
1534  {
1535  solve_transpose(&CC_jacobian, residuals, result);
1536  }
1537  }
1538  }
1539 
1540  // Set the sign of the jacobian
1541  //(this is computed in the LU decomposition phase)
1542  problem_pt->sign_of_jacobian() = Serial_sign_of_determinant_of_matrix;
1543  }
1544  }
void solve_transpose(Problem *const &problem_pt, DoubleVector &result)
Definition: linear_solver.cc:1293

References oomph::DoubleVector::build(), oomph::DistributableLinearAlgebraObject::build_distribution(), oomph::DoubleVector::built(), clean_up_memory(), oomph::Problem::communicator_pt(), oomph::LinearSolver::Compute_gradient, oomph::TimingHelpers::convert_secs_to_formatted_string(), Default, Distributed, oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::LinearSolver::Doc_time, oomph::Problem::get_jacobian(), oomph::LinearSolver::Gradient_for_glob_conv_newton_solve, oomph::LinearSolver::Gradient_has_been_computed, Jacobian_setup_time, oomph::CRDoubleMatrix::multiply_transpose(), oomph::CCDoubleMatrix::multiply_transpose(), oomph::Problem::ndof(), oomph::OomphCommunicator::nproc(), oomph::oomph_info, oomph::DoubleVector::redistribute(), Serial_compressed_row_flag, Serial_sign_of_determinant_of_matrix, oomph::Problem::sign_of_jacobian(), Solver_type, Suppress_solve, and oomph::TimingHelpers::timer().

◆ use_compressed_column_for_superlu_serial()

void oomph::SuperLUSolver::use_compressed_column_for_superlu_serial ( )
inline

Use the compressed column format in superlu serial.

663  {
665  }

References Serial_compressed_row_flag.

◆ use_compressed_row_for_superlu_serial()

void oomph::SuperLUSolver::use_compressed_row_for_superlu_serial ( )
inline

Use the compressed row format in superlu serial.

657  {
659  }

References Serial_compressed_row_flag.

Member Data Documentation

◆ Doc_stats

bool oomph::SuperLUSolver::Doc_stats
private

Set to true to output statistics (false by default).

Referenced by backsub_serial(), backsub_transpose_serial(), clean_up_memory(), disable_doc_stats(), enable_doc_stats(), factorise_serial(), and SuperLUSolver().

◆ Jacobian_setup_time

double oomph::SuperLUSolver::Jacobian_setup_time
private

Jacobian setup time.

Referenced by jacobian_setup_time(), solve(), and solve_transpose().

◆ Serial_compressed_row_flag

◆ Serial_f_factors

void* oomph::SuperLUSolver::Serial_f_factors
private

◆ Serial_info

int oomph::SuperLUSolver::Serial_info
private

Info flag for the SuperLU solver.

Referenced by backsub_serial(), backsub_transpose_serial(), clean_up_memory(), and factorise_serial().

◆ Serial_n_dof

unsigned long oomph::SuperLUSolver::Serial_n_dof
private

The number of unknowns in the linear system.

Referenced by backsub_serial(), backsub_transpose_serial(), clean_up_memory(), factorise_serial(), and SuperLUSolver().

◆ Serial_sign_of_determinant_of_matrix

int oomph::SuperLUSolver::Serial_sign_of_determinant_of_matrix
private

Sign of the determinant of the matrix.

Referenced by factorise_serial(), solve(), solve_transpose(), and SuperLUSolver().

◆ Solution_time

double oomph::SuperLUSolver::Solution_time
private

◆ Solver_type

Type oomph::SuperLUSolver::Solver_type
private

the solver type. see SuperLU_solver_type for details.

Referenced by factorise(), get_memory_usage_for_lu_factors(), get_total_needed_memory(), set_solver_type(), solve(), solve_transpose(), and SuperLUSolver().

◆ Suppress_solve

bool oomph::SuperLUSolver::Suppress_solve
private

Suppress solve?

Referenced by solve(), solve_transpose(), and SuperLUSolver().

◆ Using_dist

bool oomph::SuperLUSolver::Using_dist
private

boolean flag indicating whether superlu dist is being used

Referenced by backsub(), backsub_transpose(), factorise(), and SuperLUSolver().


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