30#include <oomph-lib-config.h>
57 const unsigned n_dof = problem_pt->
ndof();
77 <<
"CPU for setup of Dense Jacobian: "
134 const unsigned long n = matrix_pt->
nrow();
147 for (
unsigned long i = 0;
i <
n;
i++)
150 for (
unsigned long j = 0;
j <
n;
j++)
152 double tmp = std::fabs((*matrix_pt)(
i,
j));
177 for (
unsigned long i = 0;
i <
n;
i++)
179 for (
unsigned long j = 0;
j <
n;
j++)
187 for (
unsigned long j = 0;
j <
n;
j++)
190 unsigned long imax = 0;
192 for (
unsigned long i = 0;
i <
j;
i++)
195 for (
unsigned long k = 0;
k <
i;
k++)
204 for (
unsigned long i =
j;
i <
n;
i++)
207 for (
unsigned long k = 0;
k <
j;
k++)
213 double tmp = scaling[
i] * std::fabs(
sum);
224 for (
unsigned long k = 0;
k <
n;
k++)
234 scaling[
imax] = scaling[
j];
247 for (
unsigned long i =
j + 1;
i <
n;
i++)
261 for (
unsigned i = 0;
i <
n;
i++)
327 const unsigned long n =
rhs.nrow();
328 for (
unsigned long i = 0;
i <
n; ++
i)
335 for (
unsigned long i = 0;
i <
n;
i++)
342 for (
unsigned long j =
k - 1;
j <
i;
j++)
355 for (
long i =
long(
n) - 1;
i >= 0;
i--)
376 for (
unsigned long i = 0;
i <
n; ++
i)
383 for (
unsigned long i = 0;
i <
n;
i++)
390 for (
unsigned long j =
k - 1;
j <
i;
j++)
403 for (
long i =
long(
n) - 1;
i >= 0;
i--)
425 if (
rhs.distribution_pt()->distributed())
429 <<
"The vectors rhs and result must not be distributed";
436 if (matrix_pt->
nrow() != matrix_pt->
ncol())
445 if (matrix_pt->
nrow() !=
rhs.nrow())
449 <<
"The matrix and the rhs vector must have the same number of rows.";
461 if (
dist_matrix_pt->distribution_pt()->communicator_pt()->nproc() > 1 &&
465 "Matrix must not be distributed or only one processor",
474 <<
"The matrix matrix_pt must have the same communicator as the "
476 <<
" rhs and result must have the same communicator";
484 if (
result.distribution_built())
486 if (!(*
result.distribution_pt() == *
rhs.distribution_pt()))
490 <<
"The result vector distribution has been setup; it must have the "
491 <<
"same distribution as the rhs vector.";
499 if (!
result.distribution_built())
501 result.build(
rhs.distribution_pt(), 0.0);
523 <<
"CPU for solve with DenseLU : "
597 unsigned long n_dof = problem_pt->
ndof();
618 <<
"CPU for setup of Dense Jacobian: "
637 oomph_info <<
"CPU for FD DenseLU LinearSolver: "
860 oomph_info <<
"Time to set up CRDoubleMatrix Jacobian : "
874 (!(*
result.distribution_pt() == *
this->distribution_pt())))
877 result.distribution_pt());
922 result.distribution_pt());
977 <<
"Time to set up CRDoubleMatrix Jacobian : "
990 (!(*
result.distribution_pt() == *
this->distribution_pt())))
993 result.distribution_pt());
1031 oomph_info <<
"\nTime to set up CCDoubleMatrix Jacobian: "
1044 (!(*
result.distribution_pt() == *
this->distribution_pt())))
1047 result.distribution_pt());
1097 if (matrix_pt->
nrow() != matrix_pt->
ncol())
1112 if (
cr_pt->nnz() == 0)
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).";
1126 if (matrix_pt->
nrow() !=
rhs.nrow())
1130 <<
"The matrix and the rhs vector must have the same number of rows.";
1146 <<
"The matrix matrix_pt must have the same distribution as the "
1157 if (
rhs.distribution_pt()->distributed())
1161 <<
"The matrix (matrix_pt) is not distributable and therefore the rhs"
1162 <<
" vector must not be distributed";
1172 if (!(*
result.distribution_pt() == *
rhs.distribution_pt()))
1176 <<
"The result vector distribution has been setup; it must have the "
1177 <<
"same distribution as the rhs vector.";
1219 if (
cr_pt->nnz() != 0)
1229 ((2 * ((
n_row + 1) *
sizeof(
int))) +
1230 (
n_nnz * (
sizeof(
int) +
sizeof(
double))));
1246 <<
"\n - Memory used to store the Jacobian (MB): "
1248 <<
"\n - Memory used to store the LU factors (MB): "
1250 <<
"\n - Total memory used for matrix storage (MB): "
1275 <<
"Time for LU factorisation : "
1277 <<
"\nTime for back-substitution: "
1279 <<
"\nTime for SuperLUSolver solve (ndof=" << matrix_pt->
nrow() <<
"): "
1344 oomph_info <<
"Time to set up CRDoubleMatrix Jacobian : "
1358 (!(*
result.distribution_pt() == *
this->distribution_pt())))
1361 result.distribution_pt());
1390 oomph_info <<
"Time to set up CR Jacobian : "
1406 result.distribution_pt());
1461 <<
"Time to set up CRDoubleMatrix Jacobian: "
1474 (!(*
result.distribution_pt() == *
this->distribution_pt())))
1477 result.distribution_pt());
1515 oomph_info <<
"\nTime to set up CCDoubleMatrix Jacobian: "
1528 (!(*
result.distribution_pt() == *
this->distribution_pt())))
1531 result.distribution_pt());
1580 if (matrix_pt->
nrow() != matrix_pt->
ncol())
1595 if (
cr_pt->nnz() == 0)
1599 <<
"Attempted to call SuperLu on a CRDoubleMatrix with no entries, "
1600 <<
"SuperLU would segfault (because the values array pt is "
1601 <<
"uninitialised or null).";
1609 if (matrix_pt->
nrow() !=
rhs.nrow())
1613 <<
"The matrix and the rhs vector must have the same number of rows.";
1629 <<
"The matrix matrix_pt must have the same distribution as the "
1640 if (
rhs.distribution_pt()->distributed())
1644 <<
"The matrix (matrix_pt) is not distributable and therefore the rhs"
1645 <<
" vector must not be distributed";
1655 if (!(*
result.distribution_pt() == *
rhs.distribution_pt()))
1659 <<
"The result vector distribution has been setup; it must have the "
1660 <<
"same distribution as the rhs vector.";
1702 if (
cr_pt->nnz() != 0)
1712 ((2 * ((
n_row + 1) *
sizeof(
int))) +
1713 (
n_nnz * (
sizeof(
int) +
sizeof(
double))));
1728 <<
"\n - Memory used to store the Jacobian (MB): "
1730 <<
"\n - Memory used to store the LU factors (MB): "
1732 <<
"\n - Total memory used for matrix storage (MB): "
1757 <<
"Time for LU factorisation : "
1759 <<
"\nTime for back-substitution: "
1761 <<
"\nTime for SuperLUSolver solve (ndof=" << matrix_pt->
nrow() <<
"): "
1789 oomph_info <<
"Time for SuperLUSolver solve (ndof=" <<
rhs.nrow() <<
"): "
1814 oomph_info <<
"Time for SuperLUSolver solve (ndof=" <<
rhs.nrow() <<
"): "
1876 int m = matrix_pt->
ncol();
1877 int n = matrix_pt->
nrow();
1882 <<
"N, M " <<
n <<
" " <<
m << std::endl;
1941 "To apply SuperLUSolver to a CRDoubleMatrix - it must be built",
2092 for (
int i = 0;
i < nnz;
i++)
2100 for (
int i = 0;
i < nnz;
i++)
2144 <<
" CCDoubleMatrix, CRDoubleMatrix\n"
2145 <<
"and DistributedCRDoubleMatrix matrices\n";
2156 <<
" . See the SuperLU documentation for what this means.";
2188 int n = matrix_pt->
nrow();
2192 int m = matrix_pt->
ncol();
2197 <<
"N, M " <<
n <<
" " <<
m << std::endl;
2208 int *index = 0, *start = 0;
2254 throw OomphLibError(
"SuperLU only works with CR or CC Double matrices",
2284 <<
" . See the SuperLU documentation for what this means.";
2352 if (!
rhs.distribution_pt()->built())
2364 if (!(*
rhs.distribution_pt() == *
this->distribution_pt()))
2369 warning_stream <<
"The distribution of rhs vector does not match that "
2371 warning_stream <<
"The rhs will be redistributed, which is likely to "
2374 <<
"To remove this warning you can either:\n"
2375 <<
" i) Ensure that the rhs vector has the correct distribution\n"
2376 <<
" before calling the resolve() function\n"
2377 <<
"or ii) Set the flag \n"
2378 <<
" SuperLUSolver::Suppress_incorrect_rhs_distribution_warning_in_"
2380 <<
" to be true\n\n";
2383 "SuperLUSolver::resolve()",
2397 if (!(*
result.distribution_pt() == *
rhs.distribution_pt()))
2401 <<
"The result vector distribution has been setup; it must have the "
2402 <<
"same distribution as the rhs vector.";
2441 this->distribution_pt()->communicator_pt()->mpi_comm());
2460 this->distribution_pt()->communicator_pt()->mpi_comm());
2464 throw OomphLibError(
"The matrix factors have not been stored",
2474 <<
" . See the SuperLU documentation for what this means.";
2498 <<
"need it, implement it!" << std::endl;
2530 "RHS does not have the same dimension as the linear system",
2535 if (
rhs.distribution_pt()->distributed())
2547 if (!(*
rhs.distribution_pt() == *
result.distribution_pt()))
2551 "must be the same as the "
2552 <<
"rhs distribution";
2591 <<
" . See the SuperLU documentation for what this means.";
2620 "RHS does not have the same dimension as the linear system",
2625 if (
rhs.distribution_pt()->distributed())
2637 if (!(*
rhs.distribution_pt() == *
result.distribution_pt()))
2641 "must be the same as the "
2642 <<
"rhs distribution";
2681 <<
" . See the SuperLU documentation for what this means.";
//////////////////////////////////////////////////////////////// ////////////////////////////////////...
A class for compressed row matrices. This is a distributable object.
Class of matrices containing doubles, and stored as a DenseMatrix<double>, but with solving functiona...
double Jacobian_setup_time
Jacobian setup time.
void backsub(const DoubleVector &rhs, DoubleVector &result)
Do the backsubstitution step to solve the system LU result = rhs.
void clean_up_memory()
Clean up the stored LU factors.
long * Index
Pointer to storage for the index of permutations in the LU solve.
void factorise(DoubleMatrixBase *const &matrix_pt)
Perform the LU decomposition of the matrix.
double * LU_factors
Pointer to storage for the LU decomposition.
double Solution_time
Solution time.
void solve(Problem *const &problem_pt, DoubleVector &result)
Solver: Takes pointer to problem and returns the results Vector which contains the solution of the li...
int Sign_of_determinant_of_matrix
Sign of the determinant of the matrix (obtained during the LU decomposition)
Base class for any linear algebra object that is distributable. Just contains storage for the LinearA...
void clear_distribution()
clear the distribution of this distributable linear algebra object
bool distributed() const
distribution is serial or distributed
unsigned nrow() const
access function to the number of global rows.
bool distribution_built() const
if the communicator_pt is null then the distribution is not setup then false is returned,...
unsigned nrow_local() const
access function for the num of local rows on this processor.
unsigned first_row() const
access function for the first row on this processor
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
void build_distribution(const LinearAlgebraDistribution *const dist_pt)
setup the distribution of this distributable linear algebra object
Abstract base class for matrices of doubles – adds abstract interfaces for solving,...
virtual unsigned long ncol() const =0
Return the number of columns of the matrix.
virtual unsigned long nrow() const =0
Return the number of rows of the matrix.
A vector in the mathematical sense, initially developed for linear algebra type applications....
void solve(Problem *const &problem_pt, DoubleVector &result)
Solver: Takes pointer to problem and returns the results Vector which contains the solution of the li...
double size() const
Calculate the size of the element (length, area, volume,...) in Eulerian computational coordinates....
Describes the distribution of a distributable linear algebra type object. Typically this is a contain...
OomphCommunicator * communicator_pt() const
const access to the communicator pointer
unsigned nrow() const
access function to the number of global rows.
bool Doc_time
Boolean flag that indicates whether the time taken.
bool Enable_resolve
Boolean that indicates whether the matrix (or its factors, in the case of direct solver) should be st...
bool Gradient_has_been_computed
flag that indicates whether the gradient was computed or not
DoubleVector Gradient_for_glob_conv_newton_solve
DoubleVector storing the gradient for the globally convergent Newton method.
bool Compute_gradient
flag that indicates whether the gradient required for the globally convergent Newton method should be...
static bool mpi_has_been_initialised()
return true if MPI has been initialised
static OomphCommunicator * communicator_pt()
access to global communicator. This is the oomph-lib equivalent of MPI_COMM_WORLD
An oomph-lib wrapper to the MPI_Comm communicator object. Just contains an MPI_Comm object (which is ...
An OomphLibError object which should be thrown when an run-time error is encountered....
An OomphLibWarning object which should be created as a temporary object to issue a warning....
////////////////////////////////////////////////////////////////// //////////////////////////////////...
unsigned long ndof() const
Return the number of dofs.
OomphCommunicator * communicator_pt()
access function to the oomph-lib communicator
virtual void get_jacobian(DoubleVector &residuals, DenseDoubleMatrix &jacobian)
Return the fully-assembled Jacobian and residuals for the problem Interface for the case when the Jac...
void get_fd_jacobian(DoubleVector &residuals, DenseMatrix< double > &jacobian)
Return the fully-assembled Jacobian and residuals, generated by finite differences.
int & sign_of_jacobian()
Access function for the sign of the global jacobian matrix. This will be set by the linear solver,...
bool Doc_stats
Set to true to output statistics (false by default).
bool Dist_delete_matrix_data
Delete_matrix_data flag. SuperLU_dist needs its own copy of the input matrix, therefore a copy must b...
void solve_transpose(Problem *const &problem_pt, DoubleVector &result)
Solver: Takes pointer to problem and returns the results Vector which contains the solution of the li...
static bool Suppress_incorrect_rhs_distribution_warning_in_resolve
Static flag that determines whether the warning about incorrect distribution of RHSs will be printed ...
int * Dist_index_pt
Pointer for storage of matrix rows or column indices required by SuperLU_DIST.
Type Solver_type
the solver type. see SuperLU_solver_type for details.
void backsub_serial(const DoubleVector &rhs, DoubleVector &result)
backsub method for SuperLU (serial)
void backsub_transpose_distributed(const DoubleVector &rhs, DoubleVector &result)
backsub method for SuperLU Dist
double Solution_time
Solution time.
double * Dist_value_pt
Pointer for storage of the matrix values required by SuperLU_DIST.
bool Serial_compressed_row_flag
Use compressed row version?
void solve(Problem *const &problem_pt, DoubleVector &result)
Solver: Takes pointer to problem and returns the results Vector which contains the solution of the li...
void factorise(DoubleMatrixBase *const &matrix_pt)
Do the factorisation stage Note: if Delete_matrix_data is true the function matrix_pt->clean_up_memor...
void factorise_serial(DoubleMatrixBase *const &matrix_pt)
factorise method for SuperLU (serial)
void backsub_distributed(const DoubleVector &rhs, DoubleVector &result)
backsub method for SuperLU Dist
bool Using_dist
boolean flag indicating whether superlu dist is being used
int * Dist_start_pt
Pointers for storage of matrix column or row starts.
unsigned long Serial_n_dof
The number of unknowns in the linear system.
void * Serial_f_factors
Storage for the LU factors as required by SuperLU.
void resolve_transpose(const DoubleVector &rhs, DoubleVector &result)
Resolve the (transposed) system defined by the last assembled Jacobian and the specified rhs vector i...
bool Suppress_solve
Suppress solve?
int Serial_sign_of_determinant_of_matrix
Sign of the determinant of the matrix.
bool Dist_use_global_solver
Flag that determines whether the MPIProblem based solve function uses the global or distributed versi...
double get_memory_usage_for_lu_factors()
How much memory do the LU factors take up? In bytes.
void factorise_distributed(DoubleMatrixBase *const &matrix_pt)
factorise method for SuperLU Dist
bool Dist_allow_row_and_col_permutations
If true then SuperLU_DIST is allowed to permute matrix rows and columns during factorisation....
int Dist_info
Info flag for the SuperLU solver.
bool Dist_global_solve_data_allocated
Flag is true if solve data has been generated for a global matrix.
double get_total_needed_memory()
How much memory was allocated by SuperLU? In bytes.
double Jacobian_setup_time
Jacobian setup time.
void backsub_transpose_serial(const DoubleVector &rhs, DoubleVector &result)
backsub method for SuperLU (serial)
void resolve(const DoubleVector &rhs, DoubleVector &result)
Resolve the system defined by the last assembled jacobian and the specified rhs vector if resolve has...
void * Dist_solver_data_pt
Storage for the LU factors and other data required by SuperLU.
bool Dist_distributed_solve_data_allocated
Flag is true if solve data has been generated for distributed matrix.
int Dist_npcol
Number of columns for the process grid.
void backsub(const DoubleVector &rhs, DoubleVector &result)
Do the backsubstitution for SuperLU solver Note: returns the global result Vector.
void clean_up_memory()
Clean up the memory allocated by the solver.
int Dist_nprow
Number of rows for the process grid.
void backsub_transpose(const DoubleVector &rhs, DoubleVector &result)
Do the back-substitution for transposed system of the SuperLU solver Note: Returns the global result ...
int Serial_info
Info flag for the SuperLU solver.
//////////////////////////////////////////////////////////////////////
double timer()
returns the time in seconds after some point in past
std::string convert_secs_to_formatted_string(const double &time_in_sec)
Returns a nicely formatted string from an input time in seconds; the format depends on the size of ti...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
double get_total_memory_usage_in_bytes()
Function to calculate the number of bytes used in calculating and storing the LU factors.
double get_lu_factor_memory_usage_in_bytes_dist()
Function to calculate the number of bytes used to store the LU factors.
double get_total_memory_usage_in_bytes_dist()
Function to calculate the number of bytes used in calculating and storing the LU factors.
void superlu_dist_global_matrix(int opt_flag, int allow_permutations, int n, int nnz, double *values, int *row_index, int *col_start, double *b, int nprow, int npcol, int doc, void **data, int *info, MPI_Comm comm)
void superlu_cr_to_cc(int nrow, int ncol, int nnz, double *cr_values, int *cr_index, int *cr_start, double **cc_values, int **cc_index, int **cc_start)
int superlu(int *, int *, int *, int *, double *, int *, int *, double *, int *, int *, int *, void *, int *)
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...
double get_lu_factor_memory_usage_in_bytes()
Function to calculate the number of bytes used to store the LU factors.
void superlu_dist_distributed_matrix(int opt_flag, int allow_permutations, int n, int nnz_local, int nrow_local, int first_row, double *values, int *col_index, int *row_start, double *b, int nprow, int npcol, int doc, void **data, int *info, MPI_Comm comm)