trilinos_solver.cc
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Version 1.0; svn revision $LastChangedRevision$
7 //LIC//
8 //LIC// $LastChangedDate$
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 #include "trilinos_solver.h"
31 
32 
33 namespace oomph
34 {
35 
36 
37 ///////////////////////////////////////////////////////////////////////////////
38 ///////////////////////////////////////////////////////////////////////////////
39 // functions for TrilinosAztecOOSolver class
40 ///////////////////////////////////////////////////////////////////////////////
41 ///////////////////////////////////////////////////////////////////////////////
42 
43 
44 //=============================================================================
45 /// Function which uses problem_pt's get_jacobian(...) function to
46 /// generate a linear system which is then solved. This function deletes
47 /// any existing internal data and then generates a new AztecOO solver.
48 //=============================================================================
49  void TrilinosAztecOOSolver::solve(Problem* const &problem_pt,
50  DoubleVector &solution)
51  {
52 
53 
54 // MemoryUsage::doc_memory_usage("start of TrilinosAztecOOSolver::solve");
55 // MemoryUsage::insert_comment_to_continous_top(
56 // "start of TrilinosAztecOOSolver::solve");
57 
58  // clean up from previous solve
60 
61  // if we were previously using a problem based solve then we should delete
62  // the oomphlib matrix as it was created during the last solve
64  {
65  delete Oomph_matrix_pt;
66  Oomph_matrix_pt = NULL;
67  }
68 
69  // this is a problem based solve
71 
72  // store the problem_pt
73  Problem_pt = problem_pt;
74 
75  //Get oomph-lib Jacobian matrix and residual vector
76 
77  // record the start time
78  double start_t = TimingHelpers::timer();
79 
80 // MemoryUsage::doc_memory_usage("start of get_jacobian()");
81 // MemoryUsage::insert_comment_to_continous_top("start of get_jacobian()");
82 
83  // create the residual
84  DoubleVector residual;
85 
86  // create the jacobian
87  CRDoubleMatrix* cr_matrix_pt = new CRDoubleMatrix;
88  Oomph_matrix_pt = cr_matrix_pt;
89  problem_pt->get_jacobian(residual,*cr_matrix_pt);
90  this->build_distribution(residual.distribution_pt());
91 
92  // record the end time and compute the matrix setup time
93  double end_t = TimingHelpers::timer();
94  Jacobian_setup_time = end_t-start_t;
95  if (this->Doc_time)
96  {
97  oomph_info << "Time to generate Jacobian [sec] : "
98  << Jacobian_setup_time << std::endl;
99  }
100 
101 
102 // MemoryUsage::doc_memory_usage("after get_jacobian() in trilinos solver");
103 // MemoryUsage::insert_comment_to_continous_top(
104 // "after get_jacobian() in trilinos solver");
105 
106  // store the distribution of the solution vector
107  if (!solution.built())
108  {
109  solution.build(this->distribution_pt(),0.0);
110  }
111  LinearAlgebraDistribution solution_dist(solution.distribution_pt());
112 
113  // redistribute the distribution
114  solution.redistribute(this->distribution_pt());
115 
116 // MemoryUsage::doc_memory_usage("before trilinos solve");
117 // MemoryUsage::insert_comment_to_continous_top("before trilinos solve ");
118 
119  // continue solving using matrix based solve function
120  solve(Oomph_matrix_pt, residual, solution);
121 
122 
123 // MemoryUsage::doc_memory_usage("after trilinos solve");
124 // MemoryUsage::insert_comment_to_continous_top("after trilinos solve ");
125 
126  // return to the original distribution
127  solution.redistribute(&solution_dist);
128 
129 // MemoryUsage::doc_memory_usage("end of TrilinosAztecOOSolver::solve");
130 // MemoryUsage::insert_comment_to_continous_top(
131 // "end of TrilinosAztecOOSolver::solve");
132 
133 
134 }
135 
136 
137 
138 //=============================================================================
139 /// Function to solve the linear system defined by matrix_pt and rhs.
140 /// \b NOTE 1. The matrix has to be of type CRDoubleMatrix or
141 /// DistributedCRDoubleMatrix.
142 /// \b NOTE 2. This function will delete any existing internal data and
143 /// generate a new AztecOO solver.
144 //=============================================================================
146  const DoubleVector &rhs,
147  DoubleVector &result)
148 {
149 
150  // start the timer
151  double start_t = TimingHelpers::timer();
152 
153 #ifdef PARANOID
154  // check that the matrix is square
155  if (matrix_pt->nrow() != matrix_pt->ncol())
156  {
157  std::ostringstream error_message_stream;
158  error_message_stream
159  << "The matrix at matrix_pt must be square.";
160  throw OomphLibError(error_message_stream.str(),
161  OOMPH_CURRENT_FUNCTION,
162  OOMPH_EXCEPTION_LOCATION);
163  }
164  // check that the matrix and the rhs vector have the same nrow()
165  if (matrix_pt->nrow() != rhs.nrow())
166  {
167  std::ostringstream error_message_stream;
168  error_message_stream
169  << "The matrix and the rhs vector must have the same number of rows.";
170  throw OomphLibError(error_message_stream.str(),
171  OOMPH_CURRENT_FUNCTION,
172  OOMPH_EXCEPTION_LOCATION);
173  }
174 
175  // if the matrix is distributable then it too should have the same
176  // communicator as the rhs vector and should not be distributed
177  CRDoubleMatrix* cr_matrix_pt = dynamic_cast<CRDoubleMatrix*>(matrix_pt);
178  if (cr_matrix_pt != 0)
179  {
181  if (!(temp_comm == *cr_matrix_pt->distribution_pt()->communicator_pt()))
182  {
183  std::ostringstream error_message_stream;
184  error_message_stream
185  << "The matrix matrix_pt must have the same communicator as the vectors"
186  << " rhs and result must have the same communicator";
187  throw OomphLibError(error_message_stream.str(),
188  OOMPH_CURRENT_FUNCTION,
189  OOMPH_EXCEPTION_LOCATION);
190  }
191  }
192  else
193  {
194  throw OomphLibError("Matrix must be of type CRDoubleMatrix",
195  OOMPH_CURRENT_FUNCTION,
196  OOMPH_EXCEPTION_LOCATION);
197  }
198 
199  // if the result vector is setup then check it is not distributed and has
200  // the same communicator as the rhs vector
201  if (result.built())
202  {
203  if (!(*result.distribution_pt() == *rhs.distribution_pt()))
204  {
205  std::ostringstream error_message_stream;
206  error_message_stream
207  << "The result vector distribution has been setup; it must have the "
208  << "same distribution as the rhs vector.";
209  throw OomphLibError(error_message_stream.str(),
210  OOMPH_CURRENT_FUNCTION,
211  OOMPH_EXCEPTION_LOCATION);
212  }
213  }
214 #endif
215 
216  // build the result if not built
217  if (!result.built())
218  {
219  result.build(rhs.distribution_pt(),0.0);
220  }
221 
223  {
224  // Only call the setup method if this is the first time we call the
225  // solve method
227  {
228  // setup the solver
229  solver_setup(matrix_pt);
230  // Do not call the setup again
232  // Enable resolve since we are not going to build the solver, the
233  // matrix and the wrapper to the preconditioner again
234  Enable_resolve=true;
235  }
236  }
237  else
238  {
239  // setup the solver
240  solver_setup(matrix_pt);
241  }
242 
243  // create Epetra version of r
244  Epetra_Vector* epetra_r_pt = TrilinosEpetraHelpers::
246 
247  // create an empty Epetra vector for z
248  Epetra_Vector* epetra_z_pt = TrilinosEpetraHelpers::
250 
251  double start_t_trilinos = TimingHelpers::timer();
252 
253  // solve the system
254  solve_using_AztecOO(epetra_r_pt,epetra_z_pt);
255 
256  double end_t_trilinos = TimingHelpers::timer();
257  if (this->Doc_time)
258  {
259  oomph_info << "Time for trilinos solve itself : "
260  << end_t_trilinos-start_t_trilinos
261  << "s" << std::endl;
262  }
263  // Copy result to z
265 
266  // clean up memory
267  delete epetra_r_pt;
268  delete epetra_z_pt;
269 
270  // delete solver data if required
271  if (!Enable_resolve)
272  {
273  clean_up_memory();
274  }
275 
276  // stop timers and compute solve time
277  double end_t = TimingHelpers::timer();
278  Linear_solver_solution_time = end_t-start_t;
279 
280  // output timings and info
281  if (this->Doc_time)
282  {
283  oomph_info << "Time for complete trilinos solve : "
285  << "s" << std::endl;
286  }
287 }
288 
289 
290 //=============================================================================
291 /// Helper function for setting up the solver. Converts the oomph-lib
292 /// matrices to Epetra matrices, sets up the preconditioner, creates the
293 /// Trilinos Aztec00 solver and passes in the matrix, preconditioner and
294 /// parameters.
295 //=============================================================================
297 {
298 
299  // clean up the memory
300  // - delete all except Oomph_matrix_pt, which may have been set in the
301  // problem based solve
302  clean_up_memory();
303 
304  // cast to CRDoubleMatrix
305  // note cast check performed in matrix based solve(...) method
306  CRDoubleMatrix* cast_matrix_pt = dynamic_cast<CRDoubleMatrix*>(matrix_pt);
307 
308  // store the distribution
309  // distribution of preconditioner is same as matrix
310  this->build_distribution(cast_matrix_pt->distribution_pt());
311 
312  // create the new solver
313  AztecOO_solver_pt = new AztecOO();
314 
315  // if the preconditioner is an oomph-lib preconditioner then we set it up
316  TrilinosPreconditionerBase* trilinos_prec_pt =
318  if (trilinos_prec_pt == 0)
319  {
321  {
322  // setup the preconditioner
323  // start of prec setup
324  double prec_setup_start_t = TimingHelpers::timer();
325  Preconditioner_pt->setup(matrix_pt);
326  // start of prec setup
327  double prec_setup_finish_t = TimingHelpers::timer();
328  if (Doc_time)
329  {
330  double t_prec_setup = prec_setup_finish_t - prec_setup_start_t;
331  oomph_info << "Time for preconditioner setup [sec]: "
332  << t_prec_setup << std::endl;
333  }
334 #ifdef PARANOID
336  {
337  std::ostringstream error_message;
338  error_message << "The oomph-lib preconditioner and the solver must "
339  << "have the same distribution";
340  throw OomphLibError(error_message.str(),
341  OOMPH_CURRENT_FUNCTION,
342  OOMPH_EXCEPTION_LOCATION);
343  }
344 #endif
345  }
346 
347  // wrap the oomphlib preconditioner in the Epetra_Operator derived
348  // OoomphLibPreconditionerEpetraOperator to allow it to be passed to the
349  // trilinos preconditioner
352  }
353 
354  // create the matrix
355  double start_t_matrix = TimingHelpers::timer();
357  {
360  }
361  else
362  {
365  cast_matrix_pt->distribution_pt());
366  }
367 
368  // record the end time and compute the matrix setup time
369  double end_t_matrix = TimingHelpers::timer();
370  if (trilinos_prec_pt == 0)
371  {
373  {
374  dynamic_cast<CRDoubleMatrix*>(Oomph_matrix_pt)->clear();
375  delete Oomph_matrix_pt;
376  Oomph_matrix_pt = NULL;
377  }
378 
379  // delete Oomph-lib matrix if requested
380  else if (Delete_matrix)
381  {
382  dynamic_cast<CRDoubleMatrix*>(matrix_pt)->clear();
383  }
384  }
385 
386  // output times
387  if (Doc_time)
388  {
389  oomph_info << "Time to generate Trilinos matrix : "
390  << double(end_t_matrix-start_t_matrix)
391  << "s" << std::endl;
392  }
393 
394  // set the matrix
395  AztecOO_solver_pt->SetUserMatrix(Epetra_matrix_pt);
396 
397  //set the preconditioner
398  if (trilinos_prec_pt == 0)
399  {
400  AztecOO_solver_pt->
401  SetPrecOperator(Epetra_preconditioner_pt);
402  }
403 
404 #ifdef PARANOID
405  // paranoid check the preconditioner exists
406  if (Preconditioner_pt == 0)
407  {
408  std::ostringstream error_message;
409  error_message << "Preconditioner_pt == 0. (Remember default "
410  << "preconditioner is IdentityPreconditioner)";
411  throw OomphLibError(error_message.str(),
412  OOMPH_CURRENT_FUNCTION,
413  OOMPH_EXCEPTION_LOCATION);
414  }
415 #endif
416 
417  // if the preconditioner is a trilinos preconditioner then setup the
418  // preconditioner
419  if (trilinos_prec_pt != 0)
420  {
421  // only setup the preconditioner if required
423  {
424  // start of prec setup
425  double prec_setup_start_t = TimingHelpers::timer();
426 
427  // setup the preconditioner
428  trilinos_prec_pt->set_matrix_pt(matrix_pt);
429  trilinos_prec_pt->setup(Epetra_matrix_pt);
430 
431 
432  // set the preconditioner
433  AztecOO_solver_pt->
434  SetPrecOperator(trilinos_prec_pt->epetra_operator_pt());
435 
436  // start of prec setup
437  double prec_setup_finish_t = TimingHelpers::timer();
438  if (Doc_time)
439  {
440  double t_prec_setup = prec_setup_finish_t - prec_setup_start_t;
441  oomph_info << "Time for preconditioner setup [sec]: "
442  << t_prec_setup << std::endl;
443  }
444  }
445 
446  // delete the oomph-matrix if required
448  {
449  dynamic_cast<CRDoubleMatrix*>(Oomph_matrix_pt)->clear();
450  delete Oomph_matrix_pt;
451  Oomph_matrix_pt = NULL;
452  }
453 
454  // delete Oomph-lib matrix if requested
455  else if (Delete_matrix)
456  {
457  dynamic_cast<CRDoubleMatrix*>(matrix_pt)->clear();
458  }
459  }
460 
461  // set solver options
462  if (Doc_time)
463  {
464  AztecOO_solver_pt->SetAztecOption(AZ_output, AZ_warnings);
465  }
466  else
467  {
468  AztecOO_solver_pt->SetAztecOption(AZ_output, AZ_none);
469  }
470  AztecOO_solver_pt->SetAztecOption(AZ_kspace, Max_iter);
471 
472  // set solver type
473  switch (Solver_type)
474  {
475  case CG:
476  AztecOO_solver_pt->SetAztecOption(AZ_solver, AZ_cg);
477  break;
478 
479  case GMRES:
480  AztecOO_solver_pt->SetAztecOption(AZ_solver, AZ_gmres);
481  break;
482 
483  case BiCGStab:
484  AztecOO_solver_pt->SetAztecOption(AZ_solver, AZ_bicgstab);
485  break;
486 
487  default:
488  std::ostringstream error_message;
489  error_message << "Solver_type set to incorrect value. "
490  << "Acceptable values are "
491  << CG << ", " << GMRES << " and " << BiCGStab
492  << ". Current value is " << Solver_type << ".";
493  throw OomphLibError(error_message.str(),
494  OOMPH_CURRENT_FUNCTION,
495  OOMPH_EXCEPTION_LOCATION);
496  }
497 }
498 
499 //=============================================================================
500 /// \short Function to resolve a linear system using the existing solver
501 /// data, allowing a solve with a new right hand side vector. This
502 /// function must be used after a call to solve(...) with
503 /// enable_resolve set to true.
504 //=============================================================================
506  DoubleVector &solution)
507 {
508  // start the timer
509  double start_t = TimingHelpers::timer();
510 
511 #ifdef PARANOID
512  if (Epetra_matrix_pt->NumGlobalRows() != static_cast<int>(rhs.nrow()))
513  {
514  std::ostringstream error_message;
515  error_message << "The rhs vector and the matrix must have the same number "
516  << "of rows.\n"
517  << "The rhs vector has " << rhs.nrow() << " rows.\n"
518  << "The matrix has " << Epetra_matrix_pt->NumGlobalRows()
519  << " rows.\n";
520  throw OomphLibError(error_message.str(),
521  OOMPH_CURRENT_FUNCTION,
522  OOMPH_EXCEPTION_LOCATION);
523  }
524 
525 // if the result vector is setup then check it is not distributed and has
526  // the same communicator as the rhs vector
527  if (solution.built())
528  {
529  if (!(*solution.distribution_pt() == *rhs.distribution_pt()))
530  {
531  std::ostringstream error_message_stream;
532  error_message_stream
533  << "The result vector distribution has been setup; it must have the "
534  << "same distribution as the rhs vector.";
535  throw OomphLibError(error_message_stream.str(),
536  OOMPH_CURRENT_FUNCTION,
537  OOMPH_EXCEPTION_LOCATION);
538  }
539  }
540 #endif
541 
542  // build the result if not built
543  if (!solution.built())
544  {
545  solution.build(rhs.distribution_pt(),0.0);
546  }
547 
548 
549  // create Epetra version of r
550  Epetra_Vector* epetra_r_pt = TrilinosEpetraHelpers::
552 
553  // create an empty Epetra vector for z
554  Epetra_Vector* epetra_z_pt = TrilinosEpetraHelpers::
556 
557  // solve the system
558  solve_using_AztecOO(epetra_r_pt,epetra_z_pt);
559 
560  // Copy result to z
561  if (!solution.distribution_built())
562  {
563  solution.build(rhs.distribution_pt(),0.0);
564  }
566 
567  // clean up memory
568  delete epetra_r_pt;
569  delete epetra_z_pt;
570 
571  double end_t = TimingHelpers::timer();
572  Linear_solver_solution_time = end_t-start_t;
573 
574  // output timings and info
575  if (this->Doc_time)
576  {
577  oomph_info << "Time for resolve : "
579  << "s" << std::endl;
580  }
581 }
582 
583 
584 //=============================================================================
585 /// Helper function performs the actual solve once the AztecOO
586 /// solver is set up (i.e. solver_setup() is called)
587 //=============================================================================
588 void TrilinosAztecOOSolver::solve_using_AztecOO(Epetra_Vector* &rhs_pt,
589  Epetra_Vector* &soln_pt)
590 {
591 #ifdef PARANOID
592  // check the matrix and rhs are of consistent sizes
593  if (AztecOO_solver_pt == 0 )
594  {
595  std::ostringstream error_message;
596  error_message << "Solver must be called with solve(...) "
597  << "before resolve(...) to set it up.\n";
598  throw OomphLibError(error_message.str(),
599  OOMPH_CURRENT_FUNCTION,
600  OOMPH_EXCEPTION_LOCATION);
601  }
602 #endif
603 
604  // set the vectors
605  AztecOO_solver_pt->SetLHS(soln_pt);
606  AztecOO_solver_pt->SetRHS(rhs_pt);
607 
608  // perform solve
610 
611 
612  // output iterations and final norm
613  Iterations = AztecOO_solver_pt->NumIters();
614  if (Doc_time)
615  {
616  double norm = AztecOO_solver_pt->TrueResidual();
617  oomph_info << "Linear solver iterations : "
618  << Iterations << std::endl;
619  oomph_info << "Final Relative Residual Norm: " << norm << std::endl;
620  }
621 }
622 
623 
624 ///////////////////////////////////////////////////////////////////////////////
625 ///////////////////////////////////////////////////////////////////////////////
626 ///////////////////////////////////////////////////////////////////////////////
627 
628 
629 }
virtual void set_matrix_pt(DoubleMatrixBase *matrix_pt)
Set the matrix pointer.
void solve_using_AztecOO(Epetra_Vector *&rhs_pt, Epetra_Vector *&soln_pt)
Helper function performs the actual solve once the AztecOO solver is set up.
Epetra_CrsMatrix * create_distributed_epetra_matrix_for_aztecoo(CRDoubleMatrix *oomph_matrix_pt)
create and Epetra_CrsMatrix from an oomph-lib CRDoubleMatrix. Specialisation for Trilinos AztecOO...
double Jacobian_setup_time
Stores set up time for Jacobian.
double Linear_solver_solution_time
Stores time for the solution (excludes time to set up preconditioner)
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...
bool Delete_matrix
Trilinos copies matrix data from oomph-lib&#39;s own CRDoubleMatrix or DistributedCRDoubleMatrix to Trili...
double Tolerance
Convergence tolerance.
void setup()
Broken assignment operator.
Epetra_Operator * Epetra_preconditioner_pt
A pointer to the Epetra_Operator for the preconditioner. This is only used if the preconditioner NOT ...
unsigned Iterations
Stores number of iterations used.
unsigned Max_iter
Maximum number of iterations.
bool Enable_resolve
Boolean that indicates whether the matrix (or its factors, in the case of direct solver) should be st...
Definition: linear_solver.h:80
void solve(Problem *const &problem_pt, DoubleVector &solution)
Function which uses problem_pt&#39;s get_jacobian(...) function to generate a linear system which is then...
The Problem class.
Definition: problem.h:152
Preconditioner * Preconditioner_pt
Pointer to the preconditioner.
OomphCommunicator * communicator_pt() const
const access to the communicator pointer
void resolve(const DoubleVector &rhs, DoubleVector &solution)
Function to resolve a linear system using the existing solver data, allowing a solve with a new right...
OomphInfo oomph_info
Epetra_CrsMatrix * Epetra_matrix_pt
A pointer for the linear system matrix in Epetra_CrsMatrix format.
Base class for Trilinos preconditioners as oomph-lib preconditioner.
The GMRES method.
An Epetra_Operator class for oomph-lib preconditioners. A helper class for TrilinosOomphLibPreconditi...
Epetra_CrsMatrix * create_distributed_epetra_matrix(const CRDoubleMatrix *oomph_matrix_pt, const LinearAlgebraDistribution *dist_pt)
create an Epetra_CrsMatrix from an oomph-lib CRDoubleMatrix. If oomph_matrix_pt is NOT distributed (i...
The conjugate gradient method.
bool built() const
void clean_up_memory()
Clean up method - deletes the solver, the matrices and the preconditioner.
unsigned Solver_type
Defines which solver is set up - available types are defined in AztecOO_solver_types.
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.
bool Doc_time
Boolean flag that indicates whether the time taken.
Definition: linear_solver.h:84
bool Use_aztecoo_workaround_for_epetra_matrix_setup
Use workaround for creating of epetra matrix that respects aztecoo&#39;s ordering requirements.
DoubleMatrixBase * Oomph_matrix_pt
Oomph lib matrix pointer.
void solver_setup(DoubleMatrixBase *const &matrix_pt)
Helper function for setting up the solver. Converts the oomph-lib matrices to Epetra matrices...
double timer()
returns the time in seconds after some point in past
void setup(DoubleMatrixBase *matrix_pt)
Setup the preconditioner: store the matrix pointer and the communicator pointer then call preconditio...
bool Using_problem_based_solve
Helper flag keeping track of whether we called the linear algebra or problem-based solve function...
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...
Definition: problem.cc:3852
The conjugate gradient method.
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.
Epetra_Vector * create_distributed_epetra_vector(const DoubleVector &oomph_vec)
create an Epetra_Vector from an oomph-lib DoubleVector. If oomph_vec is NOT distributed (i...
AztecOO * AztecOO_solver_pt
Pointer to the AztecOO solver.
Problem * Problem_pt
A pointer to the underlying problem (NULL if MATRIX based solve) The problem_pt is stored here in a p...
bool Use_iterative_solver_as_preconditioner
Use the iterative solver as preconditioner.
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*)
Definition: double_vector.h:61
bool Setup_preconditioner_before_solve
indicates whether the preconditioner should be setup before solve. Default = true; ...
Abstract base class for matrices of doubles – adds abstract interfaces for solving, LU decomposition and multiplication by vectors.
Definition: matrices.h:275
void copy_to_oomphlib_vector(const Epetra_Vector *epetra_vec_pt, DoubleVector &oomph_vec)
Helper function to copy the contents of a Trilinos vector to an oomph-lib distributed vector...
A class for compressed row matrices. This is a distributable object.
Definition: matrices.h:872
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
virtual unsigned long ncol() const =0
Return the number of columns of the matrix.
An oomph-lib wrapper to the MPI_Comm communicator object. Just contains an MPI_Comm object (which is ...
Definition: communicator.h:57