204 OOMPH_CURRENT_FUNCTION,
205 OOMPH_EXCEPTION_LOCATION);
211 int n = matrix_pt->
nrow();
212 int m = matrix_pt->
ncol();
215 std::ostringstream error_message_stream;
216 error_message_stream <<
"Can only solve for square matrices\n" 217 <<
"N, M " << n <<
" " << m << std::endl;
220 OOMPH_CURRENT_FUNCTION,
221 OOMPH_EXCEPTION_LOCATION);
228 std::ostringstream error_message_stream;
230 <<
"Warning: Mumps wrapper assumes that communicator is MPI_COMM_WORLD\n" 231 <<
" which is not the case, so mumps may die...\n" 232 <<
" If it does initialise oomph-lib's mpi without requesting\n" 233 <<
" the communicator to be a duplicate of MPI_COMM_WORLD\n" 234 <<
" (done via an optional boolean to MPI_Helpers::init(...)\n\n" 235 <<
" (You can suppress this warning by recompiling without\n" 236 <<
" paranoia or calling \n\n" 237 <<
" MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n" 240 "MumpsSolver::factorise()",
241 OOMPH_EXCEPTION_LOCATION);
264 if (dist_matrix_pt != 0)
271 if (cr_matrix_pt != 0)
275 if (!cr_matrix_pt->
built())
278 (
"To apply MumpsSolver to a CRDoubleMatrix - it must be built",
279 OOMPH_CURRENT_FUNCTION,OOMPH_EXCEPTION_LOCATION);
289 const int nnz_loc = int(cr_matrix_pt->
nnz());
290 const int n = matrix_pt->
nrow();
301 A_loc.resize(nnz_loc);
307 double* matrix_value_pt = cr_matrix_pt->
value();
309 int* matrix_start_pt = cr_matrix_pt->
row_start();
311 for(
int count=0;count<nnz_loc;count++)
313 A_loc[count] = matrix_value_pt[count];
314 Jcn_loc[count] = matrix_index_pt[count]+1;
315 if (count<matrix_start_pt[i_row+1])
317 Irn_loc[count] = first_row+i_row+1;
322 Irn_loc[count] = first_row+i_row+1;
329 cr_matrix_pt->
clear();
337 <<
"Time for copying matrix into MumpsSolver data structure [sec] : " 338 << t_end_copy-t_start_copy << std::endl;
367 <<
"Time for mumps analysis stage in MumpsSolver [sec] : " 368 << t_end_analyse-t_start_analyse << std::endl;
379 oomph_info <<
"Estimated max. workspace in MB: " 387 bool factorised=
false;
398 oomph_info <<
"Attempting factorisation with workspace estimate: " 400 oomph_info <<
"corresponding to Workspace_scaling_factor = " 413 oomph_info <<
"Error during mumps factorisation!\n";
424 oomph_info <<
"Increasing workspace_scaling_factor to " 440 <<
"Time for actual mumps factorisation in MumpsSolver [sec] : " 441 << t_end_factor-t_start_factor<< std::endl;
447 std::ostringstream error_message_stream;
448 error_message_stream <<
"MumpsSolver only works for a " 449 <<
" distributed CRDoubleMatrix\n";
451 OOMPH_CURRENT_FUNCTION,
452 OOMPH_EXCEPTION_LOCATION);
459 std::ostringstream error_message_stream;
460 error_message_stream <<
"MumpsSolver implemented only for " 461 <<
"distributed CRDoubleMatrix. \n";
463 OOMPH_CURRENT_FUNCTION,
464 OOMPH_EXCEPTION_LOCATION);
472 oomph_info <<
"Time for MumpsSolver factorisation [sec] : " 473 << t_end-t_start << std::endl;
496 if (this->
distribution_pt()->communicator_pt()->mpi_comm()!=MPI_COMM_WORLD)
498 std::ostringstream error_message_stream;
500 <<
"Warning: Mumps wrapper assumes that communicator is MPI_COMM_WORLD\n" 501 <<
" which is not the case, so mumps may die...\n" 502 <<
" If it does initialise oomph-lib's mpi without requesting\n" 503 <<
" the communicator to be a duplicate of MPI_COMM_WORLD\n" 504 <<
" (done via an optional boolean to MPI_Helpers::init(...)\n\n" 505 <<
" (You can suppress this warning by recompiling without\n" 506 <<
" paranoia or calling \n\n" 507 <<
" MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n" 510 "MumpsSolver::backsub()",
511 OOMPH_EXCEPTION_LOCATION);
518 std::ostringstream error_message_stream;
520 <<
"Mumps has not been initialised.";
522 OOMPH_CURRENT_FUNCTION,
523 OOMPH_EXCEPTION_LOCATION);
529 std::ostringstream error_message_stream;
531 <<
"The vectors rhs must be setup";
533 OOMPH_CURRENT_FUNCTION,
534 OOMPH_EXCEPTION_LOCATION);
546 std::ostringstream warning_stream;
548 <<
"The distribution of rhs vector does not match that of the solver.\n";
550 <<
"The rhs may have to be redistributed but we're not doing this because\n" 551 <<
"I'm no longer convinced it's necessary. Keep an eye on this...\n";
553 <<
"To remove this warning you can either:\n" 554 <<
" i) Ensure that the rhs vector has the correct distribution\n" 555 <<
" before calling the resolve() function\n" 556 <<
"or ii) Set the flag \n" 557 <<
" MumpsSolver::Suppress_incorrect_rhs_distribution_warning_in_resolve\n" 558 <<
" to be true\n\n";
561 "MumpsSolver::resolve()",
562 OOMPH_EXCEPTION_LOCATION);
579 std::ostringstream error_message_stream;
581 <<
"The result vector distribution has been setup; it must have the " 582 <<
"same distribution as the rhs vector.";
584 OOMPH_CURRENT_FUNCTION,
585 OOMPH_EXCEPTION_LOCATION);
624 for (
unsigned j=0;j<n;j++)
630 MPI_Bcast(&tmp_rhs[0],ndof,MPI_DOUBLE,0,
650 oomph_info <<
"Time for MumpsSolver backsub [sec] : " 651 << t_end-t_start << std::endl;
684 if (dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt)
688 std::ostringstream error_message_stream;
690 <<
"Warning: Mumps wrapper assumes that communicator is MPI_COMM_WORLD\n" 691 <<
" which is not the case, so mumps may die...\n" 692 <<
" If it does initialise oomph-lib's mpi without requesting\n" 693 <<
" the communicator to be a duplicate of MPI_COMM_WORLD\n" 694 <<
" (done via an optional boolean to MPI_Helpers::init(...)\n\n" 695 <<
" (You can suppress this warning by recompiling without\n" 696 <<
" paranoia or calling \n\n" 697 <<
" MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n" 700 "MumpsSolver::solve()",
701 OOMPH_EXCEPTION_LOCATION);
713 std::ostringstream error_message_stream;
715 <<
"The vectors rhs must be setup";
717 OOMPH_CURRENT_FUNCTION,
718 OOMPH_EXCEPTION_LOCATION);
722 if (matrix_pt->
nrow() != matrix_pt->
ncol())
724 std::ostringstream error_message_stream;
726 <<
"The matrix at matrix_pt must be square.";
728 OOMPH_CURRENT_FUNCTION,
729 OOMPH_EXCEPTION_LOCATION);
733 if (matrix_pt->
nrow() != rhs.
nrow())
735 std::ostringstream error_message_stream;
737 <<
"The matrix and the rhs vector must have the same number of rows.";
739 OOMPH_CURRENT_FUNCTION,
740 OOMPH_EXCEPTION_LOCATION);
748 if (ddist_matrix_pt != 0)
752 std::ostringstream error_message_stream;
754 <<
"The matrix matrix_pt must have the same distribution as the " 757 OOMPH_CURRENT_FUNCTION,
758 OOMPH_EXCEPTION_LOCATION);
767 std::ostringstream error_message_stream;
769 <<
"The matrix (matrix_pt) is not distributable and therefore the rhs" 770 <<
" vector must not be distributed";
772 OOMPH_CURRENT_FUNCTION,
773 OOMPH_EXCEPTION_LOCATION);
782 std::ostringstream error_message_stream;
784 <<
"The result vector distribution has been setup; it must have the " 785 <<
"same distribution as the rhs vector.";
787 OOMPH_CURRENT_FUNCTION,
788 OOMPH_EXCEPTION_LOCATION);
823 oomph_info <<
"Time for MumpsSolver solve [sec] : " 824 << t_end-t_start << std::endl;
853 std::ostringstream error_message_stream;
855 <<
"Warning: Mumps wrapper assumes that communicator is MPI_COMM_WORLD\n" 856 <<
" which is not the case, so mumps may die...\n" 857 <<
" If it does initialise oomph-lib's mpi without requesting\n" 858 <<
" the communicator to be a duplicate of MPI_COMM_WORLD\n" 859 <<
" (done via an optional boolean to MPI_Helpers::init(...)\n\n" 860 <<
" (You can suppress this warning by recompiling without\n" 861 <<
" paranoia or calling \n\n" 862 <<
" MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n" 865 "MumpsSolver::solve()",
866 OOMPH_EXCEPTION_LOCATION);
875 unsigned n_dof = problem_pt->
ndof();
902 oomph_info <<
"Time to set up CRDoubleMatrix Jacobian [sec] : " 914 if((result.
built()) &&
920 solve(&jacobian,residuals,result);
925 solve(&jacobian,residuals,result);
936 oomph_info <<
"Total time for MumpsSolver " <<
"(np=" 938 <<
",N=" << problem_pt->
ndof()
939 <<
") [sec] : " << t_end-t_start << std::endl;
956 if (this->
distribution_pt()->communicator_pt()->mpi_comm()!=MPI_COMM_WORLD)
958 std::ostringstream error_message_stream;
960 <<
"Warning: Mumps wrapper assumes communicator is MPI_COMM_WORLD\n" 961 <<
" which is not the case, so mumps may die...\n" 962 <<
" If it does initialise oomph-lib's mpi without requesting\n" 963 <<
" the communicator to be a duplicate of MPI_COMM_WORLD\n" 964 <<
" (done via an optional boolean to MPI_Helpers::init(...)\n\n" 965 <<
" (You can suppress this warning by recompiling without\n" 966 <<
" paranoia or calling\n\n" 967 <<
" MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n" 970 "MumpsSolver::resolve()",
971 OOMPH_EXCEPTION_LOCATION);
999 oomph_info <<
"Time for MumpsSolver solve [sec]: " 1000 << t_end-t_start << std::endl;
int * column_index()
Access to C-style column index array.
unsigned long nnz() const
Return the number of nonzero entries (the local nnz)
double Solution_time
Solution time.
unsigned Workspace_scaling_factor
bool Doc_stats
Set to true for MumpsSolver to output statistics (false by default).
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...
static bool Suppress_incorrect_rhs_distribution_warning_in_resolve
Static flag that determines whether the warning about incorrect distribution of RHSs will be printed ...
bool built() const
access function to the Built flag - indicates whether the matrix has been build - i...
static int Default_workspace_scaling_factor
Default factor for workspace – static so it can be overwritten globally.
bool Enable_resolve
Boolean that indicates whether the matrix (or its factors, in the case of direct solver) should be st...
void initialise_mumps()
Initialise instance of mumps data structure.
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 ...
MumpsSolver()
Constructor: Call setup.
unsigned nrow() const
access function to the number of global rows.
bool distributed() const
access function to the distributed - indicates whether the distribution is serial or distributed ...
double Jacobian_setup_time
Jacobian setup time.
OomphCommunicator * communicator_pt()
access function to the oomph-lib communicator
double * value()
Access to C-style value array.
bool distribution_built() const
bool Delete_matrix_data
Delete_matrix_data flag. MumpsSolver needs its own copy of the input matrix, therefore a copy must be...
void backsub(const DoubleVector &rhs, DoubleVector &result)
Do the backsubstitution for mumps solver Note: returns the global result Vector.
DMUMPS_STRUC_C * Mumps_struc_pt
Pointer to MUMPS struct that contains the solver data.
Vector< int > Irn_loc
Vector for row numbers.
bool distributed() const
distribution is serial or distributed
bool Mumps_is_initialised
Has mumps been initialised?
void resolve(const DoubleVector &rhs, DoubleVector &result)
Resolve the system defined by the last assembled Jacobian and the specified rhs vector if resolve has...
Describes the distribution of a distributable linear algebra type object. Typically this is a contain...
void build(const DoubleVector &old_vector)
Just copys the argument DoubleVector.
Base class for any linear algebra object that is distributable. Just contains storage for the LinearA...
bool Doc_time
Boolean flag that indicates whether the time taken.
unsigned first_row() const
access function for the first row on this processor
void factorise(DoubleMatrixBase *const &matrix_pt)
Do the factorisation stage Note: if Delete_matrix_data is true the function matrix_pt->clean_up_memor...
bool Suppress_mumps_info_during_solve
Boolean to suppress info being printed to screen during MUMPS solve.
bool Suppress_warning_about_MPI_COMM_WORLD
Boolean to suppress warning about communicator not equal to MPI_COMM_WORLD.
double timer()
returns the time in seconds after some point in past
unsigned long ndof() const
Return the number of dofs.
void clean_up_memory()
Clean up the memory allocated by the mumps solver.
~MumpsSolver()
Destructor: Cleanup.
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 solve(Problem *const &problem_pt, DoubleVector &result)
Solver: Takes pointer to problem and returns the results Vector which contains the solution of the li...
unsigned nrow() const
access function to the number of global rows.
virtual unsigned long nrow() const =0
Return the number of rows of the matrix.
void build_distribution(const LinearAlgebraDistribution *const dist_pt)
setup the distribution of this distributable linear algebra object
A vector in the mathematical sense, initially developed for linear algebra type applications. If MPI then this vector can be distributed - its distribution is described by the LinearAlgebraDistribution object at Distribution_pt. Data is stored in a C-style pointer vector (double*)
int * row_start()
Access to C-style row_start array.
Abstract base class for matrices of doubles – adds abstract interfaces for solving, LU decomposition and multiplication by vectors.
A class for compressed row matrices. This is a distributable object.
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
virtual unsigned long ncol() const =0
Return the number of columns of the matrix.
bool Suppress_solve
Suppress solve?
void shutdown_mumps()
Shutdown mumps.