oomph::MumpsSolver Class Reference

Wrapper to Mumps solver. More...

#include <mumps_solver.h>

+ Inheritance diagram for oomph::MumpsSolver:

Public Member Functions

 MumpsSolver ()
 Constructor: Call setup. More...
 
 MumpsSolver (const MumpsSolver &dummy)=delete
 Broken copy constructor. More...
 
void operator= (const MumpsSolver &)=delete
 Broken assignment operator. More...
 
 ~MumpsSolver ()
 Destructor: Cleanup. More...
 
void disable_resolve ()
 Overload disable resolve so that it cleans up memory too. More...
 
void enable_suppress_warning_about_MPI_COMM_WORLD ()
 
void disable_suppress_warning_about_MPI_COMM_WORLD ()
 Don't suppress warning about communicator not equal to MPI_COMM_WORLD. More...
 
void enable_suppress_mumps_info_during_solve ()
 
void disable_suppress_mumps_info_during_solve ()
 Don't suppress info being printed to screen during MUMPS solve. More...
 
void solve (Problem *const &problem_pt, DoubleVector &result)
 
void solve (DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &result)
 
void resolve (const DoubleVector &rhs, DoubleVector &result)
 
void enable_doc_stats ()
 Enable documentation of statistics. More...
 
void disable_doc_stats ()
 Disable documentation of statistics. More...
 
double jacobian_setup_time ()
 
virtual double linear_solver_solution_time ()
 
void enable_suppress_solve ()
 
void disable_suppress_solve ()
 
void enable_delete_matrix_data ()
 
void disable_delete_matrix_data ()
 
void factorise (DoubleMatrixBase *const &matrix_pt)
 
void backsub (const DoubleVector &rhs, DoubleVector &result)
 
void clean_up_memory ()
 Clean up the memory allocated by the mumps solver. More...
 
void declare_jacobian_is_unsymmetric ()
 Tell MUMPS that the Jacobian matrix is unsymmetric. More...
 
void declare_jacobian_is_symmetric ()
 Tell MUMPS that the Jacobian matrix is general symmetric. More...
 
void declare_jacobian_is_symmetric_positive_definite ()
 Tell MUMPS that the Jacobian matrix is symmetric positive-definite. More...
 
void use_pord_ordering ()
 
void use_metis_ordering ()
 
void use_scotch_ordering ()
 
- 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 (Problem *const &problem_pt, DoubleVector &result)
 
virtual void solve_transpose (DoubleMatrixBase *const &matrix_pt, const DoubleVector &rhs, DoubleVector &result)
 
virtual void solve_transpose (DoubleMatrixBase *const &matrix_pt, const Vector< double > &rhs, Vector< double > &result)
 
virtual void resolve_transpose (const DoubleVector &rhs, DoubleVector &result)
 
virtual double jacobian_setup_time () const
 
virtual double linear_solver_solution_time () const
 
virtual void enable_computation_of_gradient ()
 
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)
 

Static Public Attributes

static bool Suppress_incorrect_rhs_distribution_warning_in_resolve
 
static int Default_workspace_scaling_factor = 5
 

Private Types

enum  MumpsJacobianSymmetryFlags { Unsymmetric = 0 , Symmetric_positive_definite = 1 , Symmetric = 2 }
 
enum  MumpsJacobianOrderingFlags { Scotch_ordering = 3 , Pord_ordering = 4 , Metis_ordering = 5 }
 

Private Member Functions

void initialise_mumps ()
 Initialise instance of mumps data structure. More...
 
void shutdown_mumps ()
 Shutdown mumps. 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 for MumpsSolver to output statistics (false by default). More...
 
bool Suppress_warning_about_MPI_COMM_WORLD
 
bool Suppress_mumps_info_during_solve
 Boolean to suppress info being printed to screen during MUMPS solve. More...
 
bool Mumps_is_initialised
 Has mumps been initialised? More...
 
unsigned Workspace_scaling_factor
 
bool Delete_matrix_data
 
Vector< intIrn_loc
 Vector for row numbers. More...
 
Vector< intJcn_loc
 
Vector< doubleA_loc
 
DMUMPS_STRUC_C * Mumps_struc_pt
 Pointer to MUMPS struct that contains the solver data. More...
 
unsigned Jacobian_symmetry_flag
 
unsigned Jacobian_ordering_flag
 

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

Wrapper to Mumps solver.

Member Enumeration Documentation

◆ MumpsJacobianOrderingFlags

ordering library to use for serial analysis; magic numbers as defined by MUMPS documentation

Enumerator
Scotch_ordering 
Pord_ordering 
Metis_ordering 
312  {
313  Scotch_ordering = 3,
314  Pord_ordering = 4,
315  Metis_ordering = 5
316  };
@ Pord_ordering
Definition: mumps_solver.h:314
@ Metis_ordering
Definition: mumps_solver.h:315
@ Scotch_ordering
Definition: mumps_solver.h:313

◆ MumpsJacobianSymmetryFlags

values of the SYM variable used by the MUMPS solver which dictates the symmetry properties of the Jacobian matrix; magic numbers as defined by MUMPS documentation

Enumerator
Unsymmetric 
Symmetric_positive_definite 
Symmetric 
303  {
304  Unsymmetric = 0,
306  Symmetric = 2
307  };
@ Unsymmetric
Definition: mumps_solver.h:304
@ Symmetric_positive_definite
Definition: mumps_solver.h:305
@ Symmetric
Definition: mumps_solver.h:306

Constructor & Destructor Documentation

◆ MumpsSolver() [1/2]

oomph::MumpsSolver::MumpsSolver ( )

Constructor: Call setup.

70  : Suppress_solve(false),
71  Doc_stats(false),
74  Mumps_is_initialised(false),
76  Delete_matrix_data(false),
77  Mumps_struc_pt(nullptr),
78  Jacobian_symmetry_flag(MumpsJacobianSymmetryFlags::Unsymmetric),
79  Jacobian_ordering_flag(MumpsJacobianOrderingFlags::Metis_ordering)
80  {
81  }
DMUMPS_STRUC_C * Mumps_struc_pt
Pointer to MUMPS struct that contains the solver data.
Definition: mumps_solver.h:297
unsigned Jacobian_ordering_flag
Definition: mumps_solver.h:325
bool Mumps_is_initialised
Has mumps been initialised?
Definition: mumps_solver.h:274
bool Suppress_warning_about_MPI_COMM_WORLD
Definition: mumps_solver.h:268
unsigned Workspace_scaling_factor
Definition: mumps_solver.h:277
bool Suppress_solve
Suppress solve?
Definition: mumps_solver.h:261
bool Delete_matrix_data
Definition: mumps_solver.h:285
bool Doc_stats
Set to true for MumpsSolver to output statistics (false by default).
Definition: mumps_solver.h:264
unsigned Jacobian_symmetry_flag
Definition: mumps_solver.h:320
bool Suppress_mumps_info_during_solve
Boolean to suppress info being printed to screen during MUMPS solve.
Definition: mumps_solver.h:271
static int Default_workspace_scaling_factor
Definition: mumps_solver.h:209

◆ MumpsSolver() [2/2]

oomph::MumpsSolver::MumpsSolver ( const MumpsSolver dummy)
delete

Broken copy constructor.

◆ ~MumpsSolver()

oomph::MumpsSolver::~MumpsSolver ( )

Destructor: Cleanup.

Destructor: Shutdown mumps.

169  {
170  shutdown_mumps();
171  }
void shutdown_mumps()
Shutdown mumps.
Definition: mumps_solver.cc:141

References shutdown_mumps().

Member Function Documentation

◆ backsub()

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

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

Do the backsubstitution for mumps solver. This does not make any assumption about the distribution of the vectors

527  {
528  double t_start = TimingHelpers::timer();
529 
530 #ifdef PARANOID
532  {
533  if (this->distribution_pt()->communicator_pt()->mpi_comm() !=
534  MPI_COMM_WORLD)
535  {
536  std::ostringstream error_message_stream;
537  error_message_stream
538  << "Warning: Mumps wrapper assumes that communicator is "
539  "MPI_COMM_WORLD\n"
540  << " which is not the case, so mumps may die...\n"
541  << " If it does initialise oomph-lib's mpi without "
542  "requesting\n"
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"
548  << " "
549  "MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n"
550  << " \n";
551  OomphLibWarning(error_message_stream.str(),
552  "MumpsSolver::backsub()",
554  }
555  }
556 
557  // Initialised?
559  {
560  std::ostringstream error_message_stream;
561  error_message_stream << "Mumps has not been initialised.";
562  throw OomphLibError(error_message_stream.str(),
565  }
566 
567  // check that the rhs vector is setup
568  if (!rhs.distribution_pt()->built())
569  {
570  std::ostringstream error_message_stream;
571  error_message_stream << "The vectors rhs must be setup";
572  throw OomphLibError(error_message_stream.str(),
575  }
576 
577 #endif
578 
579  // Check that the rhs distribution is the same as the distribution as this
580  // solver. If not redistribute and issue a warning
581  LinearAlgebraDistribution rhs_distribution(rhs.distribution_pt());
582  if (!(*rhs.distribution_pt() == *this->distribution_pt()))
583  {
585  {
586  std::ostringstream warning_stream;
587  warning_stream << "The distribution of rhs vector does not match that "
588  "of the solver.\n";
589  warning_stream
590  << "The rhs may have to be redistributed but we're not doing this "
591  "because\n"
592  << "I'm no longer convinced it's necessary. Keep an eye on this...\n";
593  warning_stream
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_"
599  "resolve\n"
600  << " to be true\n\n";
601 
602  OomphLibWarning(warning_stream.str(),
603  "MumpsSolver::resolve()",
605  }
606 
607  // //Have to cast away const-ness (which tells us that we shouldn't really
608  // //be doing this!)
609  // const_cast<DoubleVector&>(rhs).redistribute(this->distribution_pt());
610  }
611 
612 
613 #ifdef PARANOID
614  // if the result vector is setup then check it has the same distribution
615  // as the rhs
616  if (result.distribution_built())
617  {
618  if (!(*result.distribution_pt() == *rhs.distribution_pt()))
619  {
620  std::ostringstream error_message_stream;
621  error_message_stream
622  << "The result vector distribution has been setup; it must have the "
623  << "same distribution as the rhs vector.";
624  throw OomphLibError(error_message_stream.str(),
627  }
628  }
629 #endif
630 
631 
632  // Doc stats?
633  if (Doc_stats)
634  {
635  // Output stream for global info on host. Negative value suppresses
636  // printing
637  Mumps_struc_pt->ICNTL(3) = 6;
638  }
639 
640  // number of DOFs
641  int ndof = this->distribution_pt()->nrow();
642 
643  // Make backup to avoid over-writing
644  DoubleVector tmp_rhs;
645  tmp_rhs = rhs;
646 
647  // Now turn this into a global (non-distributed) vector
648  // because that's what mumps needs
649 
650  // Make a global distribution (i.e. one that isn't distributed)
651  LinearAlgebraDistribution global_distribution(
652  this->distribution_pt()->communicator_pt(), ndof, false);
653 
654  // Redistribute the tmp_rhs vector with this distribution -- it's
655  // now "global", as required for mumps
656  tmp_rhs.redistribute(&global_distribution);
657 
658  // Do the backsubsitution phase -- overwrites the tmp_rhs vector with the
659  // solution
660  Mumps_struc_pt->rhs = &tmp_rhs[0];
661  Mumps_struc_pt->job = 3;
662  dmumps_c(Mumps_struc_pt);
663 
664  // Copy back
665  unsigned n = Mumps_struc_pt->n;
666  for (unsigned j = 0; j < n; j++)
667  {
668  tmp_rhs[j] = Mumps_struc_pt->rhs[j];
669  }
670 
671  // Broadcast the result which is only held on root
672  MPI_Bcast(&tmp_rhs[0],
673  ndof,
674  MPI_DOUBLE,
675  0,
676  this->distribution_pt()->communicator_pt()->mpi_comm());
677 
678  // If the result vector is distributed, re-distribute the
679  // non-distributed tmp_rhs vector to match
680  if (result.built())
681  {
682  tmp_rhs.redistribute(result.distribution_pt());
683  }
684  else
685  {
686  tmp_rhs.redistribute(this->distribution_pt());
687  }
688 
689  // Now copy the tmp_rhs vector into the (matching) result
690  result = tmp_rhs;
691 
692  if ((Doc_time) &&
693  (this->distribution_pt()->communicator_pt()->my_rank() == 0))
694  {
695  double t_end = TimingHelpers::timer();
696  oomph_info << "Time for MumpsSolver backsub : "
698  t_start)
699  << std::endl;
700  }
701 
702  // Switch off docing again by setting output stream for global info on
703  // to negative number
704  Mumps_struc_pt->ICNTL(3) = -1;
705  }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
std::vector< double > DoubleVector
loads clump configuration
Definition: ClumpInput.h:26
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
bool Doc_time
Boolean flag that indicates whether the time taken.
Definition: linear_solver.h:77
static bool Suppress_incorrect_rhs_distribution_warning_in_resolve
Definition: mumps_solver.h:66
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
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References oomph::DoubleVector::built(), oomph::LinearAlgebraDistribution::built(), oomph::TimingHelpers::convert_secs_to_formatted_string(), oomph::DistributableLinearAlgebraObject::distribution_built(), oomph::DistributableLinearAlgebraObject::distribution_pt(), Doc_stats, oomph::LinearSolver::Doc_time, j, Mumps_is_initialised, Mumps_struc_pt, n, oomph::LinearAlgebraDistribution::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, oomph::DoubleVector::redistribute(), Suppress_incorrect_rhs_distribution_warning_in_resolve, Suppress_warning_about_MPI_COMM_WORLD, and oomph::TimingHelpers::timer().

Referenced by resolve(), and solve().

◆ clean_up_memory()

void oomph::MumpsSolver::clean_up_memory ( )
virtual

Clean up the memory allocated by the mumps solver.

Clean up the memory allocated for the MumpsSolver solver.

Reimplemented from oomph::LinearSolver.

711  {
712  shutdown_mumps();
713  }

References shutdown_mumps().

Referenced by oomph::NewMumpsPreconditioner::clean_up_memory(), disable_resolve(), and solve().

◆ declare_jacobian_is_symmetric()

void oomph::MumpsSolver::declare_jacobian_is_symmetric ( )
inline

Tell MUMPS that the Jacobian matrix is general symmetric.

219  {
221  }

References Jacobian_symmetry_flag, and Symmetric.

◆ declare_jacobian_is_symmetric_positive_definite()

void oomph::MumpsSolver::declare_jacobian_is_symmetric_positive_definite ( )
inline

Tell MUMPS that the Jacobian matrix is symmetric positive-definite.

References Jacobian_symmetry_flag, and Symmetric_positive_definite.

◆ declare_jacobian_is_unsymmetric()

void oomph::MumpsSolver::declare_jacobian_is_unsymmetric ( )
inline

Tell MUMPS that the Jacobian matrix is unsymmetric.

213  {
215  }

References Jacobian_symmetry_flag, and Unsymmetric.

◆ disable_delete_matrix_data()

void oomph::MumpsSolver::disable_delete_matrix_data ( )
inline

Unset Delete_matrix_data flag. MumpsSolver needs its own copy of the input matrix, therefore a copy must be made if any matrix used with this solver is to be preserved. If the input matrix can be deleted the flag can be set to true to reduce the amount of memory required, and the matrix data will be wiped using its clean_up_memory() function. Default value is false.

191  {
192  Delete_matrix_data = false;
193  }

References Delete_matrix_data.

◆ disable_doc_stats()

void oomph::MumpsSolver::disable_doc_stats ( )
inline

Disable documentation of statistics.

140  {
141  Doc_stats = false;
142  }

References Doc_stats.

◆ disable_resolve()

void oomph::MumpsSolver::disable_resolve ( )
inlinevirtual

Overload disable resolve so that it cleans up memory too.

Reimplemented from oomph::LinearSolver.

82  {
85  }
virtual void disable_resolve()
Definition: linear_solver.h:144
void clean_up_memory()
Clean up the memory allocated by the mumps solver.
Definition: mumps_solver.cc:710

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

◆ disable_suppress_mumps_info_during_solve()

void oomph::MumpsSolver::disable_suppress_mumps_info_during_solve ( )
inline

Don't suppress info being printed to screen during MUMPS solve.

109  {
111  }

References Suppress_mumps_info_during_solve.

◆ disable_suppress_solve()

void oomph::MumpsSolver::disable_suppress_solve ( )
inline

Unset the flag so that the system is actually solved again This is the default (obviously)

169  {
170  Suppress_solve = false;
171  }

References Suppress_solve.

◆ disable_suppress_warning_about_MPI_COMM_WORLD()

void oomph::MumpsSolver::disable_suppress_warning_about_MPI_COMM_WORLD ( )
inline

Don't suppress warning about communicator not equal to MPI_COMM_WORLD.

96  {
98  }

References Suppress_warning_about_MPI_COMM_WORLD.

◆ enable_delete_matrix_data()

void oomph::MumpsSolver::enable_delete_matrix_data ( )
inline

Set Delete_matrix_data flag. MumpsSolver needs its own copy of the input matrix, therefore a copy must be made if any matrix used with this solver is to be preserved. If the input matrix can be deleted the flag can be set to true to reduce the amount of memory required, and the matrix data will be wiped using its clean_up_memory() function. Default value is false.

180  {
181  Delete_matrix_data = true;
182  }

References Delete_matrix_data.

◆ enable_doc_stats()

void oomph::MumpsSolver::enable_doc_stats ( )
inline

Enable documentation of statistics.

134  {
135  Doc_stats = true;
136  }

References Doc_stats.

◆ enable_suppress_mumps_info_during_solve()

void oomph::MumpsSolver::enable_suppress_mumps_info_during_solve ( )
inline

Set boolean to suppress info being printed to screen during MUMPS solve

103  {
105  }

References Suppress_mumps_info_during_solve.

◆ enable_suppress_solve()

void oomph::MumpsSolver::enable_suppress_solve ( )
inline

Set the flag to avoid solution of the system, so just assemble the Jacobian and the rhs. (Used only for timing runs, obviously)

162  {
163  Suppress_solve = true;
164  }

References Suppress_solve.

◆ enable_suppress_warning_about_MPI_COMM_WORLD()

void oomph::MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD ( )
inline

Set boolean to suppress warning about communicator not equal to MPI_COMM_WORLD

90  {
92  }

References Suppress_warning_about_MPI_COMM_WORLD.

◆ factorise()

void oomph::MumpsSolver::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 using mumps. The resulting matrix factors are stored internally. Note: if Delete_matrix_data is true the function matrix_pt->clean_up_memory() will be used to wipe the matrix data.

181  {
182  // Initialise timer
183  double t_start = TimingHelpers::timer();
184 
185  // set the distribution
186  DistributableLinearAlgebraObject* dist_matrix_pt =
187  dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt);
188  if (dist_matrix_pt)
189  {
190  // the solver has the same distribution as the matrix if possible
191  this->build_distribution(dist_matrix_pt->distribution_pt());
192  }
193  else
194  {
195  throw OomphLibError("Matrix must be distributable",
198  }
199 
200 
201  // Check that we have a square matrix
202 #ifdef PARANOID
203  int n = matrix_pt->nrow();
204  int m = matrix_pt->ncol();
205  if (n != m)
206  {
207  std::ostringstream error_message_stream;
208  error_message_stream << "Can only solve for square matrices\n"
209  << "N, M " << n << " " << m << std::endl;
210 
211  throw OomphLibError(error_message_stream.str(),
214  }
216  {
217  if (this->distribution_pt()->communicator_pt()->mpi_comm() !=
218  MPI_COMM_WORLD)
219  {
220  std::ostringstream error_message_stream;
221  error_message_stream
222  << "Warning: Mumps wrapper assumes that communicator is "
223  "MPI_COMM_WORLD\n"
224  << " which is not the case, so mumps may die...\n"
225  << " If it does initialise oomph-lib's mpi without "
226  "requesting\n"
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"
232  << " "
233  "MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n"
234  << " \n";
235  OomphLibWarning(error_message_stream.str(),
236  "MumpsSolver::factorise()",
238  }
239  }
240 
241 #endif
242 
243  // Initialise
245  {
246  shutdown_mumps();
247  }
249 
250 
251  // Doc stats?
252  if (Doc_stats)
253  {
254  // Output stream for global info on host. Negative value suppresses
255  // printing
256  Mumps_struc_pt->ICNTL(3) = 6;
257  }
258 
259  // number of processors
260  unsigned nproc = 1;
261  if (dist_matrix_pt != 0)
262  {
263  nproc = dist_matrix_pt->distribution_pt()->communicator_pt()->nproc();
264  }
265 
266  // Is it a CRDoubleMatrix?
267  CRDoubleMatrix* cr_matrix_pt = dynamic_cast<CRDoubleMatrix*>(matrix_pt);
268  if (cr_matrix_pt != 0)
269  {
270 #ifdef PARANOID
271  // paranoid check that the matrix has been set up
272  if (!cr_matrix_pt->built())
273  {
274  throw OomphLibError(
275  "To apply MumpsSolver to a CRDoubleMatrix - it must be built",
278  }
279 #endif
280 
281  // if the matrix is distributed then set up solver
282  if ((nproc == 1) || (cr_matrix_pt->distributed()))
283  {
284  double t_start_copy = TimingHelpers::timer();
285 
286  // Find the number of rows and non-zero entries in the matrix
287  const int nnz_loc = int(cr_matrix_pt->nnz());
288  const int n = matrix_pt->nrow();
289 
290  // Create mumps storage
291 
292  // Create vector for row numbers
293  Irn_loc.resize(nnz_loc);
294 
295  // Create vector for column numbers
296  Jcn_loc.resize(nnz_loc);
297 
298  // Vector for entries
299  A_loc.resize(nnz_loc);
300 
301  // First row held on this processor
302  int first_row = cr_matrix_pt->first_row();
303 
304  // Copy into coordinate storage scheme using pointer arithmetic
305  double* matrix_value_pt = cr_matrix_pt->value();
306  int* matrix_index_pt = cr_matrix_pt->column_index();
307  int* matrix_start_pt = cr_matrix_pt->row_start();
308  int i_row = 0;
309 
310  // is the matrix symmetric? If so, we must only provide
311  // MUMPS with the upper (or lower) triangular part of the Jacobian
312  if (Mumps_struc_pt->sym != MumpsJacobianSymmetryFlags::Unsymmetric)
313  {
314  oomph_info << "Assuming Jacobian matrix is symmetric "
315  << "(passing MUMPS the upper triangular part)"
316  << std::endl;
317  }
318 
319  for (int count = 0; count < nnz_loc; count++)
320  {
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])
324  {
325  Irn_loc[count] = first_row + i_row + 1;
326  }
327  else
328  {
329  i_row++;
330  Irn_loc[count] = first_row + i_row + 1;
331  }
332 
333  // only pass the upper triangular part (and diagonal)
334  // if we have a symmetric matrix (MUMPS sums values,
335  // so need to set the lwoer triangle to zero)
336  if ((Mumps_struc_pt->sym !=
337  MumpsJacobianSymmetryFlags::Unsymmetric) &&
338  (Irn_loc[count] > Jcn_loc[count]))
339  {
340  A_loc[count] = 0.0;
341  }
342  }
343 
344  // Now delete the matrix if we are allowed
345  if (Delete_matrix_data == true)
346  {
347  cr_matrix_pt->clear();
348  }
349 
350  if ((Doc_time) &&
351  (this->distribution_pt()->communicator_pt()->my_rank() == 0))
352  {
353  double t_end_copy = TimingHelpers::timer();
354  oomph_info << "Time for copying matrix into MumpsSolver data "
355  "structure : "
357  t_end_copy - t_start_copy)
358  << std::endl;
359  }
360 
361  // Call mumps factorisation
362  //-------------------------
363 
364  // Specify size of system
365  Mumps_struc_pt->n = n;
366 
367  // Number of nonzeroes
368  Mumps_struc_pt->nz_loc = nnz_loc;
369 
370  // The entries
371  Mumps_struc_pt->irn_loc = &Irn_loc[0];
372  Mumps_struc_pt->jcn_loc = &Jcn_loc[0];
373  Mumps_struc_pt->a_loc = &A_loc[0];
374 
375  double t_start_analyse = TimingHelpers::timer();
376 
377  // Do analysis
378  Mumps_struc_pt->job = 1;
379  dmumps_c(Mumps_struc_pt);
380 
381 
382  if ((Doc_time) &&
383  (this->distribution_pt()->communicator_pt()->my_rank() == 0))
384  {
385  double t_end_analyse = TimingHelpers::timer();
386  oomph_info
387  << "Time for mumps analysis stage in MumpsSolver : "
389  t_start_analyse)
390  << "\n(Ordering generated using: ";
391 
392  switch (Mumps_struc_pt->INFOG(7))
393  {
394  case MumpsJacobianOrderingFlags::Scotch_ordering:
395  oomph_info << "SCOTCH";
396  break;
397  case MumpsJacobianOrderingFlags::Pord_ordering:
398  oomph_info << "PORD";
399  break;
400  case MumpsJacobianOrderingFlags::Metis_ordering:
401  oomph_info << "METIS";
402  break;
403  default:
404  oomph_info << Mumps_struc_pt->INFOG(7);
405  }
406 
407  oomph_info << ")" << std::endl;
408  }
409 
410 
411  int my_rank = this->distribution_pt()->communicator_pt()->my_rank();
412 
413  // Document estimate for size of workspace
414  if (my_rank == 0)
415  {
417  {
418  oomph_info << "Estimated max. workspace in MB: "
419  << Mumps_struc_pt->INFOG(26) << std::endl;
420  }
421  }
422 
423  double t_start_factor = TimingHelpers::timer();
424 
425  // Loop until successfully factorised
426  bool factorised = false;
427  while (!factorised)
428  {
429  // Set workspace to multiple of that -- ought to be "significantly
430  // larger than infog(26)", according to the manual :(
431  Mumps_struc_pt->ICNTL(23) =
433 
435  {
436  oomph_info << "Attempting factorisation with workspace estimate: "
437  << Mumps_struc_pt->ICNTL(23) << " MB\n";
438  oomph_info << "corresponding to Workspace_scaling_factor = "
439  << Workspace_scaling_factor << "\n";
440  }
441 
442  // Do factorisation
443  Mumps_struc_pt->job = 2;
444  dmumps_c(Mumps_struc_pt);
445 
446  // Check for error
447  if (Mumps_struc_pt->INFOG(1) != 0)
448  {
450  {
451  oomph_info << "Error during mumps factorisation!\n";
452  oomph_info << "Error codes: " << Mumps_struc_pt->INFO(1) << " "
453  << Mumps_struc_pt->INFO(2) << std::endl;
454  }
455 
456  // Increase scaling factor for workspace and run again
458 
460  {
461  oomph_info << "Increasing workspace_scaling_factor to "
462  << Workspace_scaling_factor << std::endl;
463  }
464  }
465  else
466  {
467  factorised = true;
468  }
469  }
470 
471 
472  if ((Doc_time) &&
473  (this->distribution_pt()->communicator_pt()->my_rank() == 0))
474  {
475  double t_end_factor = TimingHelpers::timer();
476  oomph_info << "Time for actual mumps factorisation in MumpsSolver"
477  " : "
479  t_end_factor - t_start_factor)
480  << std::endl;
481  }
482  }
483  // else the CRDoubleMatrix is not distributed
484  else
485  {
486  std::ostringstream error_message_stream;
487  error_message_stream << "MumpsSolver only works for a "
488  << " distributed CRDoubleMatrix\n";
489  throw OomphLibError(error_message_stream.str(),
492  }
493  }
494  // Otherwise throw an error
495  else
496  {
497  std::ostringstream error_message_stream;
498  error_message_stream << "MumpsSolver implemented only for "
499  << "distributed CRDoubleMatrix. \n";
500  throw OomphLibError(error_message_stream.str(),
503  }
504 
505 
506  if ((Doc_time) &&
507  (this->distribution_pt()->communicator_pt()->my_rank() == 0))
508  {
509  double t_end = TimingHelpers::timer();
510  oomph_info << "Time for MumpsSolver factorisation : "
512  t_start)
513  << std::endl;
514  }
515 
516  // Switch off docing again by setting output stream for global info on
517  // to negative number
518  Mumps_struc_pt->ICNTL(3) = -1;
519  }
unsigned first_row() const
access function for the first row on this processor
Definition: linear_algebra_distribution.h:481
void build_distribution(const LinearAlgebraDistribution *const dist_pt)
Definition: linear_algebra_distribution.h:507
DistributableLinearAlgebraObject()
Default constructor - create a distribution.
Definition: linear_algebra_distribution.h:438
OomphCommunicator * communicator_pt() const
const access to the communicator pointer
Definition: linear_algebra_distribution.h:335
Vector< int > Jcn_loc
Definition: mumps_solver.h:291
Vector< double > A_loc
Definition: mumps_solver.h:294
Vector< int > Irn_loc
Vector for row numbers.
Definition: mumps_solver.h:288
void initialise_mumps()
Initialise instance of mumps data structure.
Definition: mumps_solver.cc:86
int my_rank() const
my rank
Definition: communicator.h:176
return int(ret)+1
int * m
Definition: level2_cplx_impl.h:294

References A_loc, oomph::DistributableLinearAlgebraObject::build_distribution(), oomph::CRDoubleMatrix::built(), oomph::CRDoubleMatrix::clear(), oomph::CRDoubleMatrix::column_index(), oomph::LinearAlgebraDistribution::communicator_pt(), oomph::TimingHelpers::convert_secs_to_formatted_string(), Delete_matrix_data, oomph::DistributableLinearAlgebraObject::distributed(), oomph::DistributableLinearAlgebraObject::distribution_pt(), Doc_stats, oomph::LinearSolver::Doc_time, oomph::DistributableLinearAlgebraObject::first_row(), initialise_mumps(), int(), Irn_loc, Jcn_loc, m, Mumps_is_initialised, Mumps_struc_pt, oomph::OomphCommunicator::my_rank(), n, oomph::DoubleMatrixBase::ncol(), oomph::CRDoubleMatrix::nnz(), oomph::OomphCommunicator::nproc(), oomph::DoubleMatrixBase::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, oomph::CRDoubleMatrix::row_start(), shutdown_mumps(), Suppress_mumps_info_during_solve, Suppress_warning_about_MPI_COMM_WORLD, oomph::TimingHelpers::timer(), oomph::CRDoubleMatrix::value(), and Workspace_scaling_factor.

Referenced by oomph::NewMumpsPreconditioner::setup(), and solve().

◆ initialise_mumps()

void oomph::MumpsSolver::initialise_mumps ( )
private

Initialise instance of mumps data structure.

87  {
88  // Make new instance of Mumps data structure
89  Mumps_struc_pt = new DMUMPS_STRUC_C;
90 
91  // Mumps' hack to indicate that mpi_comm_world is used. Conversion of any
92  // other communicators appears to be non-portable, so we simply
93  // issue a warning if we later discover that oomph-lib's communicator
94  // is not MPI_COMM_WORLD
95  Mumps_struc_pt->comm_fortran = -987654;
96 
97  // Root processor participates in solution
98  Mumps_struc_pt->par = 1;
99 
100  // Set matrix symmetry properties
101  // (unsymmetric / symmetric positive definite / general symmetric)
103 
104  // First call does the initialise phase
105  Mumps_struc_pt->job = -1;
106 
107  // Call c interface to double precision mumps to initialise
108  dmumps_c(Mumps_struc_pt);
109  Mumps_is_initialised = true;
110 
111  // Output stream for global info on host. Negative value suppresses printing
112  Mumps_struc_pt->ICNTL(3) = -1;
113 
114  // Only show error messages and stats
115  // (4 for full doc; creates huge amount of output)
116  Mumps_struc_pt->ICNTL(4) = 2;
117 
118  // Write matrix
119  // sprintf(Mumps_struc_pt->write_problem,"/work/e173/e173/mheil/matrix");
120 
121  // Assembled matrix (rather than element-by_element)
122  Mumps_struc_pt->ICNTL(5) = 0;
123 
124  // set the package to use for ordering during (sequential) analysis
126 
127  // Distributed problem with user-specified distribution
128  Mumps_struc_pt->ICNTL(18) = 3;
129 
130  // Dense RHS
131  Mumps_struc_pt->ICNTL(20) = 0;
132 
133  // Non-distributed solution
134  Mumps_struc_pt->ICNTL(21) = 0;
135  }

References Jacobian_ordering_flag, Jacobian_symmetry_flag, Mumps_is_initialised, and Mumps_struc_pt.

Referenced by factorise().

◆ jacobian_setup_time()

double oomph::MumpsSolver::jacobian_setup_time ( )
inline

Returns the time taken to assemble the Jacobian matrix and residual vector

147  {
148  return Jacobian_setup_time;
149  }
double Jacobian_setup_time
Jacobian setup time.
Definition: mumps_solver.h:255

References Jacobian_setup_time.

◆ linear_solver_solution_time()

virtual double oomph::MumpsSolver::linear_solver_solution_time ( )
inlinevirtual

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

154  {
155  return Solution_time;
156  }
double Solution_time
Solution time.
Definition: mumps_solver.h:258

References Solution_time.

◆ operator=()

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

Broken assignment operator.

◆ resolve()

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

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.

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.

1006  {
1007 #ifdef PARANOID
1009  {
1010  if (this->distribution_pt()->communicator_pt()->mpi_comm() !=
1011  MPI_COMM_WORLD)
1012  {
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 "
1018  "requesting\n"
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"
1024  << " "
1025  "MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n"
1026  << " \n";
1027  OomphLibWarning(error_message_stream.str(),
1028  "MumpsSolver::resolve()",
1030  }
1031  }
1032 #endif
1033 
1034  // Store starting time for solve
1035  double t_start = TimingHelpers::timer();
1036 
1037  // Doc stats?
1038  if (Doc_stats)
1039  {
1040  // Output stream for global info on host. Negative value suppresses
1041  // printing
1042  Mumps_struc_pt->ICNTL(3) = 6;
1043  }
1044 
1045  // Now do the back substitution phase
1046  backsub(rhs, result);
1047 
1048  // Doc time for solve
1049  double t_end = TimingHelpers::timer();
1050  Solution_time = t_end - t_start;
1051 
1052  // Switch off docing again by setting output stream for global info on
1053  // to negative number
1054  Mumps_struc_pt->ICNTL(3) = -1;
1055 
1056  if ((Doc_time) &&
1057  (this->distribution_pt()->communicator_pt()->my_rank() == 0))
1058  {
1059  oomph_info << "Time for MumpsSolver solve: "
1061  t_start)
1062  << std::endl;
1063  }
1064  }
void backsub(const DoubleVector &rhs, DoubleVector &result)
Definition: mumps_solver.cc:526

References backsub(), oomph::TimingHelpers::convert_secs_to_formatted_string(), oomph::DistributableLinearAlgebraObject::distribution_pt(), Doc_stats, oomph::LinearSolver::Doc_time, Mumps_struc_pt, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, Solution_time, Suppress_warning_about_MPI_COMM_WORLD, and oomph::TimingHelpers::timer().

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

◆ shutdown_mumps()

void oomph::MumpsSolver::shutdown_mumps ( )
private

Shutdown mumps.

142  {
144  {
145  // Shut down flag
146  Mumps_struc_pt->job = -2;
147 
148  // Call c interface to double precision mumps to shut down
149  dmumps_c(Mumps_struc_pt);
150 
151  // Cleanup
152  delete Mumps_struc_pt;
153  Mumps_struc_pt = 0;
154 
155  Mumps_is_initialised = false;
156 
157  // Cleanup storage
158  Irn_loc.clear();
159  Jcn_loc.clear();
160  A_loc.clear();
161  }
162  }

References A_loc, Irn_loc, Jcn_loc, Mumps_is_initialised, and Mumps_struc_pt.

Referenced by clean_up_memory(), factorise(), and ~MumpsSolver().

◆ solve() [1/2]

void oomph::MumpsSolver::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. Matrix must be CRDoubleMatrix. 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.

727  {
728 #ifdef PARANOID
730  {
731  if (dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt)
732  ->distribution_pt()
733  ->communicator_pt()
734  ->mpi_comm() != MPI_COMM_WORLD)
735  {
736  std::ostringstream error_message_stream;
737  error_message_stream
738  << "Warning: Mumps wrapper assumes that communicator is "
739  "MPI_COMM_WORLD\n"
740  << " which is not the case, so mumps may die...\n"
741  << " If it does initialise oomph-lib's mpi without "
742  "requesting\n"
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"
748  << " "
749  "MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n"
750  << " \n";
751  OomphLibWarning(error_message_stream.str(),
752  "MumpsSolver::solve()",
754  }
755  }
756 #endif
757 
758  // Initialise timer
759  double t_start = TimingHelpers::timer();
760 
761 #ifdef PARANOID
762  // check that the rhs vector is setup
763  if (!rhs.distribution_pt()->built())
764  {
765  std::ostringstream error_message_stream;
766  error_message_stream << "The vectors rhs must be setup";
767  throw OomphLibError(error_message_stream.str(),
770  }
771 
772  // check that the matrix is square
773  if (matrix_pt->nrow() != matrix_pt->ncol())
774  {
775  std::ostringstream error_message_stream;
776  error_message_stream << "The matrix at matrix_pt must be square.";
777  throw OomphLibError(error_message_stream.str(),
780  }
781 
782  // check that the matrix and the rhs vector have the same nrow()
783  if (matrix_pt->nrow() != rhs.nrow())
784  {
785  std::ostringstream error_message_stream;
786  error_message_stream
787  << "The matrix and the rhs vector must have the same number of rows.";
788  throw OomphLibError(error_message_stream.str(),
791  }
792 
793 
794  // if the matrix is distributable then should have the same distribution
795  // as the rhs vector
796  DistributableLinearAlgebraObject* ddist_matrix_pt =
797  dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt);
798  if (ddist_matrix_pt != 0)
799  {
800  if (!(*ddist_matrix_pt->distribution_pt() == *rhs.distribution_pt()))
801  {
802  std::ostringstream error_message_stream;
803  error_message_stream
804  << "The matrix matrix_pt must have the same distribution as the "
805  << "rhs vector.";
806  throw OomphLibError(error_message_stream.str(),
809  }
810  }
811  // if the matrix is not distributable then it the rhs vector should not be
812  // distributed
813  else
814  {
815  if (rhs.distribution_pt()->distributed())
816  {
817  std::ostringstream error_message_stream;
818  error_message_stream
819  << "The matrix (matrix_pt) is not distributable and therefore the rhs"
820  << " vector must not be distributed";
821  throw OomphLibError(error_message_stream.str(),
824  }
825  }
826  // if the result vector is setup then check it has the same distribution
827  // as the rhs
828  if (result.built())
829  {
830  if (!(*result.distribution_pt() == *rhs.distribution_pt()))
831  {
832  std::ostringstream error_message_stream;
833  error_message_stream
834  << "The result vector distribution has been setup; it must have the "
835  << "same distribution as the rhs vector.";
836  throw OomphLibError(error_message_stream.str(),
839  }
840  }
841 
842 #endif
843 
844 
845  // set the distribution
846  DistributableLinearAlgebraObject* dist_matrix_pt =
847  dynamic_cast<DistributableLinearAlgebraObject*>(matrix_pt);
848  if (dist_matrix_pt)
849  {
850  // the solver has the same distribution as the matrix if possible
851  this->build_distribution(dist_matrix_pt->distribution_pt());
852  }
853  else
854  {
855  // the solver has the same distribution as the RHS
856  this->build_distribution(rhs.distribution_pt());
857  }
858 
859  // Factorise the matrix
860  factorise(matrix_pt);
861 
862  // Now do the back solve
863  backsub(rhs, result);
864 
865  // Doc time for solve
866  double t_end = TimingHelpers::timer();
867  Solution_time = t_end - t_start;
868 
869  if ((Doc_time) &&
870  (this->distribution_pt()->communicator_pt()->my_rank() == 0))
871  {
872  oomph_info << "Time for MumpsSolver solve : "
874  t_start)
875  << std::endl;
876  }
877 
878  // Switch off docing again by setting output stream for global info on
879  // to negative number
880  Mumps_struc_pt->ICNTL(3) = -1;
881 
882  // If we are not storing the solver data for resolves, delete it
883  if (!Enable_resolve)
884  {
885  clean_up_memory();
886  }
887  }
bool Enable_resolve
Definition: linear_solver.h:73
void factorise(DoubleMatrixBase *const &matrix_pt)
Definition: mumps_solver.cc:180

References backsub(), oomph::DistributableLinearAlgebraObject::build_distribution(), oomph::DoubleVector::built(), oomph::LinearAlgebraDistribution::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(), Mumps_struc_pt, oomph::DoubleMatrixBase::ncol(), oomph::DistributableLinearAlgebraObject::nrow(), oomph::DoubleMatrixBase::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, Solution_time, Suppress_warning_about_MPI_COMM_WORLD, and oomph::TimingHelpers::timer().

◆ solve() [2/2]

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

895  {
896 #ifdef PARANOID
898  {
899  if (problem_pt->communicator_pt()->mpi_comm() != MPI_COMM_WORLD)
900  {
901  std::ostringstream error_message_stream;
902  error_message_stream
903  << "Warning: Mumps wrapper assumes that communicator is "
904  "MPI_COMM_WORLD\n"
905  << " which is not the case, so mumps may die...\n"
906  << " If it does initialise oomph-lib's mpi without "
907  "requesting\n"
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"
913  << " "
914  "MumpsSolver::enable_suppress_warning_about_MPI_COMM_WORLD()\n\n"
915  << " \n";
916  OomphLibWarning(error_message_stream.str(),
917  "MumpsSolver::solve()",
919  }
920  }
921 #endif
922 
923  // Initialise timer
924  double t_start = TimingHelpers::timer();
925 
926  // number of dofs
927  unsigned n_dof = problem_pt->ndof();
928 
929  // Set the distribution for the solver.
930  this->distribution_pt()->build(problem_pt->communicator_pt(), n_dof);
931 
932  // Take a copy of Delete_matrix_data
933  bool copy_of_Delete_matrix_data = Delete_matrix_data;
934 
935  // Set Delete_matrix to true
936  Delete_matrix_data = true;
937 
938  // Initialise timer
939  t_start = TimingHelpers::timer();
940 
941  // Storage for the distributed residuals vector
942  DoubleVector residuals(this->distribution_pt(), 0.0);
943 
944  // Get the sparse jacobian and residuals of the problem
945  CRDoubleMatrix jacobian(this->distribution_pt());
946  problem_pt->get_jacobian(residuals, jacobian);
947 
948  // Doc time for setup
949  double t_end = TimingHelpers::timer();
950  Jacobian_setup_time = t_end - t_start;
951  int my_rank = this->distribution_pt()->communicator_pt()->my_rank();
952  if ((Doc_time) && (my_rank == 0))
953  {
954  oomph_info << "Time to set up CRDoubleMatrix Jacobian : "
957  << std::endl;
958  }
959 
960 
961  // Now call the linear algebra solve, if desired
962  if (!Suppress_solve)
963  {
964  // If the distribution of the result has been build and
965  // does not match that of
966  // the solver then redistribute before the solve and return
967  // to the incoming distribution afterwards.
968  if ((result.built()) &&
969  (!(*result.distribution_pt() == *this->distribution_pt())))
970  {
971  LinearAlgebraDistribution temp_global_dist(result.distribution_pt());
972  result.build(this->distribution_pt(), 0.0);
973  solve(&jacobian, residuals, result);
974  result.redistribute(&temp_global_dist);
975  }
976  else
977  {
978  solve(&jacobian, residuals, result);
979  }
980  }
981 
982  // Set Delete_matrix back to original value
983  Delete_matrix_data = copy_of_Delete_matrix_data;
984 
985  // Finalise/doc timings
986  if ((Doc_time) && (my_rank == 0))
987  {
988  double t_end = TimingHelpers::timer();
989  oomph_info << "Total time for MumpsSolver "
990  << "(np="
991  << this->distribution_pt()->communicator_pt()->nproc()
992  << ",N=" << problem_pt->ndof() << ") : "
994  t_start)
995  << std::endl;
996  }
997  }
void build(const OomphCommunicator *const comm_pt, const unsigned &first_row, const unsigned &nrow_local, const unsigned &nrow=0)
Definition: linear_algebra_distribution.cc:35
void solve(Problem *const &problem_pt, DoubleVector &result)
Definition: mumps_solver.cc:894
int nproc() const
number of processors
Definition: communicator.h:157

References oomph::DoubleVector::build(), oomph::LinearAlgebraDistribution::build(), oomph::DoubleVector::built(), oomph::Problem::communicator_pt(), oomph::LinearAlgebraDistribution::communicator_pt(), oomph::TimingHelpers::convert_secs_to_formatted_string(), Delete_matrix_data, oomph::DistributableLinearAlgebraObject::distribution_pt(), oomph::LinearSolver::Doc_time, oomph::Problem::get_jacobian(), Jacobian_setup_time, oomph::OomphCommunicator::my_rank(), oomph::Problem::ndof(), oomph::OomphCommunicator::nproc(), OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, oomph::DoubleVector::redistribute(), Suppress_solve, Suppress_warning_about_MPI_COMM_WORLD, and oomph::TimingHelpers::timer().

◆ use_metis_ordering()

void oomph::MumpsSolver::use_metis_ordering ( )
inline

◆ use_pord_ordering()

void oomph::MumpsSolver::use_pord_ordering ( )
inline
231  {
233  }

References Jacobian_ordering_flag, and Pord_ordering.

◆ use_scotch_ordering()

void oomph::MumpsSolver::use_scotch_ordering ( )
inline

Member Data Documentation

◆ A_loc

Vector<double> oomph::MumpsSolver::A_loc
private

Referenced by factorise(), and shutdown_mumps().

◆ Default_workspace_scaling_factor

int oomph::MumpsSolver::Default_workspace_scaling_factor = 5
static

Default factor for workspace – static so it can be overwritten globally.

/////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// Default factor for workspace – static so it can be overwritten globally.

◆ Delete_matrix_data

bool oomph::MumpsSolver::Delete_matrix_data
private

Delete_matrix_data flag. MumpsSolver needs its own copy of the input matrix, therefore a copy must be made if any matrix used with this solver is to be preserved. If the input matrix can be deleted the flag can be set to true to reduce the amount of memory required, and the matrix data will be wiped using its clean_up_memory() function. Default value is false.

Referenced by disable_delete_matrix_data(), enable_delete_matrix_data(), factorise(), and solve().

◆ Doc_stats

bool oomph::MumpsSolver::Doc_stats
private

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

Referenced by backsub(), disable_doc_stats(), enable_doc_stats(), factorise(), and resolve().

◆ Irn_loc

Vector<int> oomph::MumpsSolver::Irn_loc
private

Vector for row numbers.

Referenced by factorise(), and shutdown_mumps().

◆ Jacobian_ordering_flag

unsigned oomph::MumpsSolver::Jacobian_ordering_flag
private

stores an integer from the public enum which specifies which package (PORD, Metis or SCOTCH) is used to reorder the Jacobian matrix during the analysis

Referenced by initialise_mumps(), use_metis_ordering(), use_pord_ordering(), and use_scotch_ordering().

◆ Jacobian_setup_time

double oomph::MumpsSolver::Jacobian_setup_time
private

Jacobian setup time.

Referenced by jacobian_setup_time(), and solve().

◆ Jacobian_symmetry_flag

unsigned oomph::MumpsSolver::Jacobian_symmetry_flag
private

symmetry of the Jacobian matrix we're solving; takes one of the enum values above

Referenced by declare_jacobian_is_symmetric(), declare_jacobian_is_symmetric_positive_definite(), declare_jacobian_is_unsymmetric(), and initialise_mumps().

◆ Jcn_loc

Vector<int> oomph::MumpsSolver::Jcn_loc
private

Referenced by factorise(), and shutdown_mumps().

◆ Mumps_is_initialised

bool oomph::MumpsSolver::Mumps_is_initialised
private

Has mumps been initialised?

Referenced by backsub(), factorise(), initialise_mumps(), and shutdown_mumps().

◆ Mumps_struc_pt

DMUMPS_STRUC_C* oomph::MumpsSolver::Mumps_struc_pt
private

Pointer to MUMPS struct that contains the solver data.

Referenced by backsub(), factorise(), initialise_mumps(), resolve(), shutdown_mumps(), and solve().

◆ Solution_time

double oomph::MumpsSolver::Solution_time
private

Solution time.

Referenced by linear_solver_solution_time(), resolve(), and solve().

◆ Suppress_incorrect_rhs_distribution_warning_in_resolve

bool oomph::MumpsSolver::Suppress_incorrect_rhs_distribution_warning_in_resolve
static
Initial value:
=
false

Static flag that determines whether the warning about incorrect distribution of RHSs will be printed or not

Static warning to suppress warnings about incorrect distribution of RHS vector. Default is false

Referenced by backsub().

◆ Suppress_mumps_info_during_solve

bool oomph::MumpsSolver::Suppress_mumps_info_during_solve
private

Boolean to suppress info being printed to screen during MUMPS solve.

Referenced by disable_suppress_mumps_info_during_solve(), enable_suppress_mumps_info_during_solve(), and factorise().

◆ Suppress_solve

bool oomph::MumpsSolver::Suppress_solve
private

Suppress solve?

Referenced by disable_suppress_solve(), enable_suppress_solve(), and solve().

◆ Suppress_warning_about_MPI_COMM_WORLD

bool oomph::MumpsSolver::Suppress_warning_about_MPI_COMM_WORLD
private

Boolean to suppress warning about communicator not equal to MPI_COMM_WORLD

Referenced by backsub(), disable_suppress_warning_about_MPI_COMM_WORLD(), enable_suppress_warning_about_MPI_COMM_WORLD(), factorise(), resolve(), and solve().

◆ Workspace_scaling_factor

unsigned oomph::MumpsSolver::Workspace_scaling_factor
private

Referenced by factorise().


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