70 : Suppress_solve(false),
72 Suppress_warning_about_MPI_COMM_WORLD(false),
73 Suppress_mumps_info_during_solve(false),
74 Mumps_is_initialised(false),
75 Workspace_scaling_factor(Default_workspace_scaling_factor),
76 Delete_matrix_data(false),
77 Mumps_struc_pt(nullptr),
196 OOMPH_CURRENT_FUNCTION,
197 OOMPH_EXCEPTION_LOCATION);
203 int n = matrix_pt->
nrow();
204 int m = matrix_pt->
ncol();
207 std::ostringstream error_message_stream;
208 error_message_stream <<
"Can only solve for square matrices\n"
209 <<
"N, M " << n <<
" " << m << std::endl;
212 OOMPH_CURRENT_FUNCTION,
213 OOMPH_EXCEPTION_LOCATION);
220 std::ostringstream error_message_stream;
222 <<
"Warning: Mumps wrapper assumes that communicator is "
224 <<
" which is not the case, so mumps may die...\n"
225 <<
" If it does initialise oomph-lib's mpi without "
227 <<
" the communicator to be a duplicate of MPI_COMM_WORLD\n"
228 <<
" (done via an optional boolean to "
229 "MPI_Helpers::init(...)\n\n"
230 <<
" (You can suppress this warning by recompiling without\n"
231 <<
" paranoia or calling \n\n"
233 "MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n"
236 "MumpsSolver::factorise()",
237 OOMPH_EXCEPTION_LOCATION);
261 if (dist_matrix_pt != 0)
268 if (cr_matrix_pt != 0)
272 if (!cr_matrix_pt->
built())
275 "To apply MumpsSolver to a CRDoubleMatrix - it must be built",
276 OOMPH_CURRENT_FUNCTION,
277 OOMPH_EXCEPTION_LOCATION);
287 const int nnz_loc = int(cr_matrix_pt->
nnz());
288 const int n = matrix_pt->
nrow();
299 A_loc.resize(nnz_loc);
305 double* matrix_value_pt = cr_matrix_pt->
value();
307 int* matrix_start_pt = cr_matrix_pt->
row_start();
312 if (
Mumps_struc_pt->sym != MumpsJacobianSymmetryFlags::Unsymmetric)
314 oomph_info <<
"Assuming Jacobian matrix is symmetric "
315 <<
"(passing MUMPS the upper triangular part)"
319 for (
int count = 0; count < nnz_loc; count++)
321 A_loc[count] = matrix_value_pt[count];
322 Jcn_loc[count] = matrix_index_pt[count] + 1;
323 if (count < matrix_start_pt[i_row + 1])
337 MumpsJacobianSymmetryFlags::Unsymmetric) &&
347 cr_matrix_pt->
clear();
354 oomph_info <<
"Time for copying matrix into MumpsSolver data "
357 t_end_copy - t_start_copy)
387 <<
"Time for mumps analysis stage in MumpsSolver : "
390 <<
"\n(Ordering generated using: ";
394 case MumpsJacobianOrderingFlags::Scotch_ordering:
397 case MumpsJacobianOrderingFlags::Pord_ordering:
400 case MumpsJacobianOrderingFlags::Metis_ordering:
418 oomph_info <<
"Estimated max. workspace in MB: "
426 bool factorised =
false;
436 oomph_info <<
"Attempting factorisation with workspace estimate: "
438 oomph_info <<
"corresponding to Workspace_scaling_factor = "
451 oomph_info <<
"Error during mumps factorisation!\n";
461 oomph_info <<
"Increasing workspace_scaling_factor to "
476 oomph_info <<
"Time for actual mumps factorisation in MumpsSolver"
479 t_end_factor - t_start_factor)
486 std::ostringstream error_message_stream;
487 error_message_stream <<
"MumpsSolver only works for a "
488 <<
" distributed CRDoubleMatrix\n";
490 OOMPH_CURRENT_FUNCTION,
491 OOMPH_EXCEPTION_LOCATION);
497 std::ostringstream error_message_stream;
498 error_message_stream <<
"MumpsSolver implemented only for "
499 <<
"distributed CRDoubleMatrix. \n";
501 OOMPH_CURRENT_FUNCTION,
502 OOMPH_EXCEPTION_LOCATION);
510 oomph_info <<
"Time for MumpsSolver factorisation : "
536 std::ostringstream error_message_stream;
538 <<
"Warning: Mumps wrapper assumes that communicator is "
540 <<
" which is not the case, so mumps may die...\n"
541 <<
" If it does initialise oomph-lib's mpi without "
543 <<
" the communicator to be a duplicate of MPI_COMM_WORLD\n"
544 <<
" (done via an optional boolean to "
545 "MPI_Helpers::init(...)\n\n"
546 <<
" (You can suppress this warning by recompiling without\n"
547 <<
" paranoia or calling \n\n"
549 "MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n"
552 "MumpsSolver::backsub()",
553 OOMPH_EXCEPTION_LOCATION);
560 std::ostringstream error_message_stream;
561 error_message_stream <<
"Mumps has not been initialised.";
563 OOMPH_CURRENT_FUNCTION,
564 OOMPH_EXCEPTION_LOCATION);
570 std::ostringstream error_message_stream;
571 error_message_stream <<
"The vectors rhs must be setup";
573 OOMPH_CURRENT_FUNCTION,
574 OOMPH_EXCEPTION_LOCATION);
586 std::ostringstream warning_stream;
587 warning_stream <<
"The distribution of rhs vector does not match that "
590 <<
"The rhs may have to be redistributed but we're not doing this "
592 <<
"I'm no longer convinced it's necessary. Keep an eye on this...\n";
594 <<
"To remove this warning you can either:\n"
595 <<
" i) Ensure that the rhs vector has the correct distribution\n"
596 <<
" before calling the resolve() function\n"
597 <<
"or ii) Set the flag \n"
598 <<
" MumpsSolver::Suppress_incorrect_rhs_distribution_warning_in_"
600 <<
" to be true\n\n";
603 "MumpsSolver::resolve()",
604 OOMPH_EXCEPTION_LOCATION);
620 std::ostringstream error_message_stream;
622 <<
"The result vector distribution has been setup; it must have the "
623 <<
"same distribution as the rhs vector.";
625 OOMPH_CURRENT_FUNCTION,
626 OOMPH_EXCEPTION_LOCATION);
666 for (
unsigned j = 0; j < n; j++)
672 MPI_Bcast(&tmp_rhs[0],
696 oomph_info <<
"Time for MumpsSolver backsub : "
734 ->mpi_comm() != MPI_COMM_WORLD)
736 std::ostringstream error_message_stream;
738 <<
"Warning: Mumps wrapper assumes that communicator is "
740 <<
" which is not the case, so mumps may die...\n"
741 <<
" If it does initialise oomph-lib's mpi without "
743 <<
" the communicator to be a duplicate of MPI_COMM_WORLD\n"
744 <<
" (done via an optional boolean to "
745 "MPI_Helpers::init(...)\n\n"
746 <<
" (You can suppress this warning by recompiling without\n"
747 <<
" paranoia or calling \n\n"
749 "MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n"
752 "MumpsSolver::solve()",
753 OOMPH_EXCEPTION_LOCATION);
765 std::ostringstream error_message_stream;
766 error_message_stream <<
"The vectors rhs must be setup";
768 OOMPH_CURRENT_FUNCTION,
769 OOMPH_EXCEPTION_LOCATION);
773 if (matrix_pt->
nrow() != matrix_pt->
ncol())
775 std::ostringstream error_message_stream;
776 error_message_stream <<
"The matrix at matrix_pt must be square.";
778 OOMPH_CURRENT_FUNCTION,
779 OOMPH_EXCEPTION_LOCATION);
783 if (matrix_pt->
nrow() != rhs.
nrow())
785 std::ostringstream error_message_stream;
787 <<
"The matrix and the rhs vector must have the same number of rows.";
789 OOMPH_CURRENT_FUNCTION,
790 OOMPH_EXCEPTION_LOCATION);
798 if (ddist_matrix_pt != 0)
802 std::ostringstream error_message_stream;
804 <<
"The matrix matrix_pt must have the same distribution as the "
807 OOMPH_CURRENT_FUNCTION,
808 OOMPH_EXCEPTION_LOCATION);
817 std::ostringstream error_message_stream;
819 <<
"The matrix (matrix_pt) is not distributable and therefore the rhs"
820 <<
" vector must not be distributed";
822 OOMPH_CURRENT_FUNCTION,
823 OOMPH_EXCEPTION_LOCATION);
832 std::ostringstream error_message_stream;
834 <<
"The result vector distribution has been setup; it must have the "
835 <<
"same distribution as the rhs vector.";
837 OOMPH_CURRENT_FUNCTION,
838 OOMPH_EXCEPTION_LOCATION);
901 std::ostringstream error_message_stream;
903 <<
"Warning: Mumps wrapper assumes that communicator is "
905 <<
" which is not the case, so mumps may die...\n"
906 <<
" If it does initialise oomph-lib's mpi without "
908 <<
" the communicator to be a duplicate of MPI_COMM_WORLD\n"
909 <<
" (done via an optional boolean to "
910 "MPI_Helpers::init(...)\n\n"
911 <<
" (You can suppress this warning by recompiling without\n"
912 <<
" paranoia or calling \n\n"
914 "MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n"
917 "MumpsSolver::solve()",
918 OOMPH_EXCEPTION_LOCATION);
927 unsigned n_dof = problem_pt->
ndof();
954 oomph_info <<
"Time to set up CRDoubleMatrix Jacobian : "
968 if ((result.
built()) &&
973 solve(&jacobian, residuals, result);
978 solve(&jacobian, residuals, result);
992 <<
",N=" << problem_pt->
ndof() <<
") : "
1013 std::ostringstream error_message_stream;
1014 error_message_stream
1015 <<
"Warning: Mumps wrapper assumes communicator is MPI_COMM_WORLD\n"
1016 <<
" which is not the case, so mumps may die...\n"
1017 <<
" If it does initialise oomph-lib's mpi without "
1019 <<
" the communicator to be a duplicate of MPI_COMM_WORLD\n"
1020 <<
" (done via an optional boolean to "
1021 "MPI_Helpers::init(...)\n\n"
1022 <<
" (You can suppress this warning by recompiling without\n"
1023 <<
" paranoia or calling\n\n"
1025 "MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n"
1028 "MumpsSolver::resolve()",
1029 OOMPH_EXCEPTION_LOCATION);
A class for compressed row matrices. This is a distributable object.
int * column_index()
Access to C-style column index array.
int * row_start()
Access to C-style row_start array.
unsigned long nnz() const
Return the number of nonzero entries (the local nnz)
bool built() const
access function to the Built flag - indicates whether the matrix has been build - i....
double * value()
Access to C-style value array.
Base class for any linear algebra object that is distributable. Just contains storage for the LinearA...
bool distributed() const
distribution is serial or distributed
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
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 first_row() const
access function for the first row on this processor
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 build(const DoubleVector &old_vector)
Just copys the argument DoubleVector.
void redistribute(const LinearAlgebraDistribution *const &dist_pt)
The contents of the vector are redistributed to match the new distribution. In a non-MPI rebuild this...
Describes the distribution of a distributable linear algebra type object. Typically this is a contain...
bool distributed() const
access function to the distributed - indicates whether the distribution is serial or distributed
OomphCommunicator * communicator_pt() const
const access to the communicator pointer
void build(const OomphCommunicator *const comm_pt, const unsigned &first_row, const unsigned &nrow_local, const unsigned &nrow=0)
Sets the distribution. Takes first_row, nrow_local and nrow as arguments. If nrow is not provided or ...
bool built() const
if the communicator_pt is null then the distribution is not setup then false is returned,...
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...
double Jacobian_setup_time
Jacobian setup time.
DMUMPS_STRUC_C * Mumps_struc_pt
Pointer to MUMPS struct that contains the solver data.
~MumpsSolver()
Destructor: Cleanup.
unsigned Jacobian_ordering_flag
stores an integer from the public enum which specifies which package (PORD, Metis or SCOTCH) is used ...
bool Mumps_is_initialised
Has mumps been initialised?
bool Suppress_warning_about_MPI_COMM_WORLD
Boolean to suppress warning about communicator not equal to MPI_COMM_WORLD.
void shutdown_mumps()
Shutdown mumps.
MumpsJacobianOrderingFlags
ordering library to use for serial analysis; magic numbers as defined by MUMPS documentation
double Solution_time
Solution time.
unsigned Workspace_scaling_factor
void resolve(const DoubleVector &rhs, DoubleVector &result)
Resolve the system defined by the last assembled Jacobian and the specified rhs vector if resolve has...
bool Suppress_solve
Suppress solve?
bool Delete_matrix_data
Delete_matrix_data flag. MumpsSolver needs its own copy of the input matrix, therefore a copy must be...
bool Doc_stats
Set to true for MumpsSolver to output statistics (false by default).
void backsub(const DoubleVector &rhs, DoubleVector &result)
Do the backsubstitution for mumps solver Note: returns the global result Vector.
Vector< int > Irn_loc
Vector for row numbers.
static bool Suppress_incorrect_rhs_distribution_warning_in_resolve
Static flag that determines whether the warning about incorrect distribution of RHSs will be printed ...
unsigned Jacobian_symmetry_flag
symmetry of the Jacobian matrix we're solving; takes one of the enum values above
MumpsSolver()
Constructor: Call setup.
bool Suppress_mumps_info_during_solve
Boolean to suppress info being printed to screen during MUMPS solve.
static int Default_workspace_scaling_factor
Default factor for workspace – static so it can be overwritten globally.
void clean_up_memory()
Clean up the memory allocated by the mumps solver.
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 initialise_mumps()
Initialise instance of mumps data structure.
void factorise(DoubleMatrixBase *const &matrix_pt)
Do the factorisation stage Note: if Delete_matrix_data is true the function matrix_pt->clean_up_memor...
MumpsJacobianSymmetryFlags
values of the SYM variable used by the MUMPS solver which dictates the symmetry properties of the Jac...
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.
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...
OomphCommunicator * communicator_pt()
access function to the oomph-lib communicator
bool Doc_stats
Boolean to indicate whether to output basic info during setup_multi_domain_interaction() routines.
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...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...