Flow123d  intersections_paper-476-gbe68821
linsys.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file linsys.hh
15  * @brief Wrappers for linear systems based on MPIAIJ and MATIS format.
16  * @author Jan Brezina
17  *
18  * Linear system only keep together matrix, RHS and the solution vector.
19  *
20  */
21 
22 //=============================================================================
23 //
24 // LINER SYSTEM ROUTINES - linear system use wrapers of PETSc assembling routins
25 // in order to allow counting of allocation and filling of matrix to be done by the same code
26 //
27 // we want to allow allocations of nonlocal rows, to this end we count on- and off-processor
28 // members in an parallel Vector
29 //
30 //=============================================================================
31 
32 #ifndef LA_LINSYS_HH_
33 #define LA_LINSYS_HH_
34 
35 /**
36  * @brief Abstract linear system class.
37  *
38  * Linear system consists of Matrix, RHS and solution.
39  * It provides general methods for:
40  * - matrix preallocation
41  * - assembling matrix and RHS
42  * - application of linear constrains (Dirichlet conditions) either during assembly or
43  * on assembled system
44  * - solution of the system
45  * - output in Matlab format
46  *
47  * Method operates on the system as single object. But some methods for matrix only manipulation
48  * can be provided until we have matrix as separate class.
49  *
50  * TODO:
51  * - simplify constructors
52  * - introduce set_solution_vector() and set_rhs() in order to solve multiple systems with same matrix
53  * - simplify constructor, make common interface, rather introduce particular seters for particular solvers
54  * - which parameters expose through Input::Record
55  * - why we need lsize in constructors if we have Distribution
56  */
57 
58 #include "system/global_defs.h"
59 #include "la/distribution.hh"
61 #include "input/accessors.hh"
62 
63 #include "local_system.hh"
64 
65 #include <mpi.h>
66 
67 #include <vector>
68 #include <armadillo>
69 
70 // PETSc includes
71 #include "petscmat.h"
72 
73 
74 class LinSys
75 {
76 friend class SchurComplement;
77 public:
78  // Abstract Input Record for LinSys initialization
80 
81  typedef enum {
82  INSERT=INSERT_VALUES,
83  ADD=ADD_VALUES,
87  } SetValuesMode;
88 
89 protected:
90  typedef std::pair<unsigned,double> Constraint_;
92 
93 public:
94  /**
95  * Constructor.
96  * Constructor of abstract class should not be called directly, but is used for initialization of member common
97  * to all particular solvers.
98  *
99  * @param comm - MPI communicator
100  *
101  * TODO: Vector solution_ is now initialized to NULL, but it should be rather allocated
102  * in the constructor instead of the method set_solution().
103  */
104  LinSys(const Distribution *rows_ds)
105  : comm_( rows_ds->get_comm() ), status_( NONE ), lsize_( rows_ds->lsize() ), rows_ds_(rows_ds),
106  symmetric_( false ), positive_definite_( false ), negative_definite_( false ),
107  spd_via_symmetric_general_( false ), solution_(NULL), v_solution_(NULL),
108  own_solution_(false)
109  {
110  int lsizeInt = static_cast<int>( rows_ds->lsize() );
111  int sizeInt;
112  MPI_Allreduce ( &lsizeInt, &sizeInt, 1, MPI_INT, MPI_SUM, comm_ );
113  size_ = static_cast<unsigned>( sizeInt );
114 
118  };
119 
120  /**
121  * Copy constructor.
122  */
123  LinSys(LinSys &other)
124  : r_tol_(other.r_tol_), a_tol_(other.a_tol_), max_it_(other.max_it_), comm_(other.comm_), status_(other.status_),
125  lsize_( other.rows_ds_->lsize() ), size_(other.size_), rows_ds_(other.rows_ds_), symmetric_(other.symmetric_),
130 
131  {
132  OLD_ASSERT( false, "Using copy constructor of LinSys is not allowed!");
133  set_solution(other.v_solution_);
134  };
135 
136  /**
137  * Returns global system size.
138  */
139  inline unsigned int size()
140  {
141  return size_;
142  }
143 
144  /**
145  * Returns local system size. (for partitioning of solution vectors)
146  * for PETSC_MPIAIJ it is also partitioning of the matrix
147  */
148  inline unsigned int vec_lsize()
149  {
150  return lsize_;
151  }
152 
153  /**
154  * Returns PETSC matrix (only for PETSC solvers)
155  *
156  * If matrix is changed, method set_matrix_changed() must be called.
157  * Example:
158  * @CODE
159  * MatDiagonalSet(schur->get_matrix(), new_diagonal, ADD_VALUES);
160  * schur->set_matrix_changed();
161  * @ENDCODE
162  */
163  virtual const Mat *get_matrix()
164  {
165  OLD_ASSERT( false, "Function get_matrix is not implemented for linsys type %s \n.", typeid(*this).name() );
166  return NULL;
167  }
168 
169  /**
170  * Returns RHS vector (only for PETSC solvers)
171  *
172  * If vector is changed, method set_rhs_changed() must be called.
173  * Example:
174  * @CODE
175  * VecScale(schur->get_rhs(), -1.0);
176  * schur->set_rhs_changed();
177  * @ENDCODE
178  */
179  virtual const Vec *get_rhs()
180  {
181  OLD_ASSERT( false, "Function get_rhs is not implemented for linsys type %s \n.", typeid(*this).name() );
182  return NULL;
183  }
184 
185  /**
186  * Sets matrix changed flag.
187  */
189  { matrix_changed_ = true;}
190 
191  /**
192  * Sets rhs changed flag (only for PETSC solvers)
193  */
195  { rhs_changed_ = true; }
196 
197  /**
198  * Set relative tolerance, absolute tolerance, and maximum number of iterations of the linear solver.
199  *
200  * For each of these three parameters we first look for the value at user input
201  * if not set we use the value provided to this method and finally the default values are
202  * set by the call of this method in the constructor.
203  */
204  virtual void set_tolerances(double r_tol, double a_tol, unsigned int max_it) = 0;
205 
206  /**
207  * Returns true if the system matrix has changed since the last solve.
208  */
210  { return matrix_changed_;}
211 
212  /**
213  * Returns true if the system RHS has changed since the last solve.
214  */
216  { return rhs_changed_;}
217 
218 
219  /**
220  * Sets PETSC matrix (only for PETSC solvers)
221  */
222  virtual PetscErrorCode set_matrix(Mat &matrix, MatStructure str)
223  {
224  OLD_ASSERT( false, "Function set_matrix is not implemented for linsys type %s \n.", typeid(*this).name() );
225  return 0;
226  }
227 
228  /**
229  * Sets RHS vector (only for PETSC solvers)
230  */
231  virtual PetscErrorCode set_rhs(Vec &rhs)
232  {
233  OLD_ASSERT( false, "Function set_rhs is not implemented for linsys type %s \n.", typeid(*this).name() );
234  return 0;
235  }
236 
237  /**
238  * Clears entries of the matrix
239  */
240  virtual PetscErrorCode mat_zero_entries()
241  {
242  OLD_ASSERT( false, "Function mat_zero_entries is not implemented for linsys type %s \n.", typeid(*this).name() );
243  return 0;
244  }
245 
246  /**
247  * Clears entries of the right-hand side
248  */
249  virtual PetscErrorCode rhs_zero_entries()
250  {
251  OLD_ASSERT( false, "Function vec_zero_entries is not implemented for linsys type %s \n.", typeid(*this).name() );
252  return 0;
253  }
254 
255  /**
256  * Returns PETSC vector with solution. Underlying array can be provided on construction.
257  */
258  const Vec &get_solution()
259  {
260  return solution_;
261  }
262 
263  /**
264  * Create PETSc solution
265  */
266  void set_solution(double *sol_array) {
267  if (sol_array == NULL) {
268  v_solution_ = new double[ rows_ds_->lsize() + 1 ];
269  own_solution_ = true;
270  }
271  else {
272  v_solution_ = sol_array;
273  own_solution_ = false;
274  }
275  PetscErrorCode ierr;
276  ierr = VecCreateMPIWithArray( comm_,1, rows_ds_->lsize(), PETSC_DECIDE, v_solution_, &solution_ ); CHKERRV( ierr );
277  }
278 
279  /**
280  * Returns PETSC subarray with solution. Underlying array can be provided on construction.
281  */
283  {
284  return v_solution_;
285  }
286 
287  /**
288  * Switch linear system into allocating assembly. (only for PETSC_MPIAIJ_preallocate_by_assembly)
289  */
290  virtual void start_allocation()
291  {
292  OLD_ASSERT( false, "Function start_allocation is not implemented for linsys type %s \n.", typeid(*this).name() );
293  }
294 
295  /**
296  * Switch linear system into adding assembly. (the only one supported by triplets ??)
297  */
298  virtual void start_add_assembly()
299  {
300  OLD_ASSERT( false, "Function start_add_assembly is not implemented for linsys type %s \n.", typeid(*this).name() );
301  }
302 
303  /**
304  * Switch linear system into insert assembly. (not currently used)
305  */
306  virtual void start_insert_assembly()
307  {
308  OLD_ASSERT( false, "Function start_insert_assembly is not implemented for linsys type %s \n.", typeid(*this).name() );
309  }
310 
311  /**
312  * Finish assembly of the whole system. For PETSC this should call MatEndAssembly with MAT_FINAL_ASSEMBLY
313  */
314  virtual void finish_assembly( )=0;
315 
316  /**
317  * Assembly full rectangular submatrix into the system matrix.
318  * Should be virtual, implemented differently in particular solvers.
319  */
320  virtual void mat_set_values(int nrow,int *rows,int ncol,int *cols,double *vals)=0;
321 
322  /**
323  * Shortcut for assembling just one element into the matrix.
324  * Similarly we can provide method accepting armadillo matrices.
325  */
326  void mat_set_value(int row,int col,double val)
327  { mat_set_values(1,&row,1,&col,&val); }
328 
329  /**
330  * Set values of the system right-hand side.
331  * Should be virtual, implemented differently in particular solvers.
332  */
333  virtual void rhs_set_values(int nrow,int *rows,double *vals)=0;
334 
335  /**
336  * Shorcut for assembling just one element into RHS vector.
337  */
338  void rhs_set_value(int row,double val)
339  { rhs_set_values(1,&row,&val); }
340 
341 
342  /// Set values in the system matrix and values in the right-hand side vector on corresponding rows.
343  inline void set_values(int nrow,int *rows,int ncol,int *cols,PetscScalar *mat_vals, PetscScalar *rhs_vals)
344  {
345  mat_set_values(nrow, rows, ncol, cols, mat_vals);
346  rhs_set_values(nrow, rows, rhs_vals);
347  }
348 
350  local.eliminate_solution();
351  arma::mat tmp = local.matrix.t();
352 // DBGCOUT(<< "\n" << tmp);
353 // DBGCOUT(<< "row dofs: \n");
354 // for(unsigned int i=0; i< local.row_dofs.size(); i++)
355 // cout << local.row_dofs[i] << " ";
356 // cout <<endl;
357 
358  // This is always done only once, see implementation.
359  mat_set_values(local.matrix.n_rows, (int *)(local.row_dofs.memptr()),
360  local.matrix.n_cols, (int *)(local.col_dofs.memptr()),
361  tmp.memptr());
362 
363  rhs_set_values(local.matrix.n_rows, (int *)(local.row_dofs.memptr()),
364  local.rhs.memptr());
365  }
366 
367  /**
368  * Add given dense matrix to preallocation.
369  */
370  //virtual void allocate(std::vector<int> rows, std::vector<int> cols);
371 
372  /**
373  * Shortcut to assembly into matrix and RHS in one call, possibly apply Dirichlet boundary conditions.
374  * @p row_dofs - are global indices of rows of dense @p matrix and rows of dense vector @rhs in global system
375  * @p col_dofs - are global indices of columns of the matrix, and possibly
376  *
377  * Application of Dirichlet conditions:
378  * 1) Rows with negative dofs are set to zero.
379  * 2) Cols with negative dofs are eliminated.
380  * 3) If there are entries on global diagonal. We determine value K either from diagonal of local matrix, or (if it is zero) from
381  * diagonal average.
382  *
383  * Caveats:
384  * - can not set dirichlet condition on zero dof
385  * - Armadillo stores matrix in column first form (Fortran like) which makes it not well suited
386  * for passing local matrices.
387  *
388  */
389  void set_values(std::vector<int> &row_dofs, std::vector<int> &col_dofs,
390  const arma::mat &matrix, const arma::vec &rhs,
391  const arma::vec &row_solution, const arma::vec &col_solution)
392 
393  {
394  arma::mat tmp = matrix.t();
395  arma::vec tmp_rhs = rhs;
396  bool negative_row = false;
397  bool negative_col = false;
398 
399  for(unsigned int l_row = 0; l_row < row_dofs.size(); l_row++)
400  if (row_dofs[l_row] < 0) {
401  tmp_rhs(l_row)=0.0;
402  tmp.col(l_row).zeros();
403  negative_row=true;
404  }
405 
406  for(unsigned int l_col = 0; l_col < col_dofs.size(); l_col++)
407  if (col_dofs[l_col] < 0) {
408  tmp_rhs -= matrix.col(l_col) * col_solution[l_col];
409  tmp.row(l_col).zeros();
410  negative_col=true;
411  }
412 
413 
414  if (negative_row && negative_col) {
415  // look for diagonal entry
416  for(unsigned int l_row = 0; l_row < row_dofs.size(); l_row++)
417  if (row_dofs[l_row] < 0)
418  for(unsigned int l_col = 0; l_col < col_dofs.size(); l_col++)
419  if (col_dofs[l_col] < 0 && row_dofs[l_row] == col_dofs[l_col]) {
420  double new_diagonal = fabs(matrix.at(l_row,l_col));
421  if (new_diagonal == 0.0) {
422  if (matrix.is_square()) {
423  new_diagonal = arma::sum( abs(matrix.diag())) / matrix.n_rows;
424  } else {
425  new_diagonal = arma::accu( abs(matrix) ) / matrix.n_elem;
426  }
427  }
428  tmp.at(l_col, l_row) = new_diagonal;
429  tmp_rhs(l_row) = new_diagonal * row_solution[l_row];
430  }
431 
432  }
433 
434  if (negative_row)
435  for(int &row : row_dofs) row=abs(row);
436 
437  if (negative_col)
438  for(int &col : col_dofs) col=abs(col);
439 
440 
441  mat_set_values(row_dofs.size(), const_cast<int *>(&(row_dofs[0])),
442  col_dofs.size(), const_cast<int *>(&(col_dofs[0])), tmp.memptr() );
443  rhs_set_values(row_dofs.size(), const_cast<int *>(&(row_dofs[0])), tmp_rhs.memptr() );
444  }
445 
446  /**
447  * Adds Dirichlet constrain.
448  * @param row - global number of row that should be eliminated.
449  * @param value - solution value at the given row
450  */
451  void add_constraint(int row, double value) {
452 
453  constraints_.push_back( Constraint_( static_cast<unsigned>( row ), value ) );
454  }
455 
456  /**
457  * Apply constrains to assembled matrix. Constrains are given by pairs: global row index, value.
458  * i.e. typedef pair<unsigned int, double> Constrain;
459  *
460  * What is th meaning of ( const double factor ) form Cambridge code?
461  */
462  virtual void apply_constrains( double scalar )=0;
463 
464  /**
465  * Solve the system and return convergence reason.
466  */
467  virtual int solve()=0;
468 
469  /**
470  * Returns norm of the initial right hand side
471  */
473  return residual_norm_;
474  };
475 
476  /**
477  * Explicitly compute residual and its norm for current solution.
478  */
479  virtual double compute_residual() =0;
480 
481  /**
482  * Returns information on relative solver accuracy
483  */
485  return r_tol_;
486  };
487 
488  /**
489  * Returns information on absolute solver accuracy
490  */
491  virtual double get_absolute_accuracy(){
492  return 0.0;
493  };
494 
495  /**
496  * Provides user knowledge about symmetry.
497  */
498  inline void set_symmetric(bool flag = true)
499  {
500  symmetric_ = flag;
501  if (!flag) {
502  set_positive_definite(false);
503  set_negative_definite(false);
504  }
505  }
506 
507  inline bool is_symmetric()
508  { return symmetric_; }
509 
510  /**
511  * Provides user knowledge about positive definiteness.
512  */
513  inline void set_positive_definite(bool flag = true)
514  {
515  positive_definite_ = flag;
516  if (flag) {
517  set_symmetric();
518  set_negative_definite(false);
519  }
520  }
521 
522  /**
523  * Provides user knowledge about negative definiteness.
524  */
525  inline void set_negative_definite(bool flag = true)
526  {
527  negative_definite_ = flag;
528  if (flag) {
529  set_symmetric();
530  set_positive_definite(false);
531  }
532  }
533 
534  inline bool is_positive_definite()
535  { return positive_definite_; }
536 
537  inline bool is_negative_definite()
538  { return negative_definite_; }
539 
540  /// TODO: In fact we want to know if the matrix is already preallocated
541  /// However to do this we need explicit finalisation of preallocating cycle.
542  inline bool is_new() {
543  return ( status_ == NONE );
544  }
545 
546  inline bool is_preallocated() {
547  return ( status_ == INSERT || status_ == ADD);
548  }
549 
550  /**
551  * Provides user knowledge about positive definiteness via symmetric general approach.
552  * This is useful for solving Darcy flow by mixed hybrid method, where blocks on subdomains are saddle point but
553  * interface among subdomains is only at the block of Lagrange multipliers and is symmetric positive definite.
554  * Problem condensed to interface can thus be solved by PCG method, although original problem is saddle point.
555  */
556  inline void set_spd_via_symmetric_general(bool flag = true)
557  {
559  if (flag) set_symmetric();
560  }
561 
563  { return spd_via_symmetric_general_; }
564 
565 
566  /**
567  * Output the system in the Matlab format possibly with given ordering.
568  * Rather we shoud provide output operator <<, since it is more flexible.
569  */
570  virtual void view()
571  {
572  OLD_ASSERT( false, "Function view is not implemented for linsys type %s \n.", typeid(*this).name() );
573  }
574 
575  /**
576  * Sets basic parameters of LinSys defined by user in input file and used to calculate
577  */
578  virtual void set_from_input(const Input::Record in_rec)
579  {
580  in_rec_ = in_rec;
582  }
583 
584  /**
585  * Get precision of solving
586  */
587  virtual double get_solution_precision() = 0;
588 
589  virtual ~LinSys()
590  {
591  PetscErrorCode ierr;
592  if ( solution_ ) { ierr = VecDestroy(&solution_); CHKERRV( ierr ); }
593  if ( own_solution_ ) delete[] v_solution_;
594  }
595 
596 protected:
597  // Default values initialized in constructor
598  static constexpr double default_r_tol_ = 1e-7;
599  static constexpr double default_a_tol_ = 1e-11;
600  static constexpr unsigned int default_max_it_ = 1000;
601 
602  double r_tol_; ///< relative tolerance of linear solver
603  double a_tol_; ///< absolute tolerance of linear solver
604  unsigned int max_it_; ///< maximum number of iterations of linear solver
605 
607  SetValuesMode status_; //!< Set value status of the linear system.
608 
609  const unsigned lsize_; //!< local number of matrix rows (non-overlapping division of rows)
610  unsigned size_; //!< global number of matrix rows, i.e. problem size
611 
612  const Distribution * rows_ds_; //!< final distribution of rows of MH matrix
613 
618 
619  bool matrix_changed_; //!< true if the matrix was changed since the last solve
620  bool rhs_changed_; //!< true if the right hand side was changed since the last solve
621 
622  Vec solution_; //!< PETSc vector constructed with vb array.
623  double *v_solution_; //!< local solution array pointing into Vec solution_
624  bool own_solution_; //!< Indicates if the solution array has been allocated by this class
625 
626  double residual_norm_; //!< local solution array pointing into Vec solution_
627 
628  ConstraintVec_ constraints_;
629 
630  std::vector<double> globalSolution_; //!< global solution in numbering for linear system
631 
632  Input::Record in_rec_; // structure contained parameters of LinSys defined in input file
633 
634 };
635 
636 #endif /* LA_LINSYS_HH_ */
unsigned int size()
Definition: linsys.hh:139
std::vector< double > globalSolution_
global solution in numbering for linear system
Definition: linsys.hh:630
SetValuesMode status_
Set value status of the linear system.
Definition: linsys.hh:607
bool is_new()
Definition: linsys.hh:542
virtual void start_insert_assembly()
Definition: linsys.hh:306
bool is_negative_definite()
Definition: linsys.hh:537
bool spd_via_symmetric_general_
Definition: linsys.hh:617
std::pair< unsigned, double > Constraint_
Definition: linsys.hh:90
double get_residual_norm()
Definition: linsys.hh:472
void set_symmetric(bool flag=true)
Definition: linsys.hh:498
double * v_solution_
local solution array pointing into Vec solution_
Definition: linsys.hh:623
int MPI_Comm
Definition: mpi.h:141
virtual void view()
Definition: linsys.hh:570
virtual void set_from_input(const Input::Record in_rec)
Definition: linsys.hh:578
bool matrix_changed_
true if the matrix was changed since the last solve
Definition: linsys.hh:619
virtual void start_add_assembly()
Definition: linsys.hh:298
virtual PetscErrorCode mat_zero_entries()
Definition: linsys.hh:240
virtual void rhs_set_values(int nrow, int *rows, double *vals)=0
void set_values(std::vector< int > &row_dofs, std::vector< int > &col_dofs, const arma::mat &matrix, const arma::vec &rhs, const arma::vec &row_solution, const arma::vec &col_solution)
Definition: linsys.hh:389
const unsigned lsize_
local number of matrix rows (non-overlapping division of rows)
Definition: linsys.hh:609
void set_rhs_changed()
Definition: linsys.hh:194
static constexpr double default_r_tol_
Definition: linsys.hh:598
bool symmetric_
Definition: linsys.hh:614
unsigned int vec_lsize()
Definition: linsys.hh:148
ConstraintVec_ constraints_
Definition: linsys.hh:628
#define MPI_SUM
Definition: mpi.h:196
bool is_matrix_changed()
Definition: linsys.hh:209
void set_negative_definite(bool flag=true)
Definition: linsys.hh:525
virtual void start_allocation()
Definition: linsys.hh:290
virtual void finish_assembly()=0
virtual double get_solution_precision()=0
DofVec col_dofs
Definition: local_system.hh:36
void add_constraint(int row, double value)
Definition: linsys.hh:451
void set_spd_via_symmetric_general(bool flag=true)
Definition: linsys.hh:556
unsigned size_
global number of matrix rows, i.e. problem size
Definition: linsys.hh:610
arma::vec rhs
local system RHS
Input::Record in_rec_
Definition: linsys.hh:632
bool rhs_changed_
true if the right hand side was changed since the last solve
Definition: linsys.hh:620
LinSys(const Distribution *rows_ds)
Definition: linsys.hh:104
void set_local_system(LocalSystem &local)
Definition: linsys.hh:349
virtual ~LinSys()
Definition: linsys.hh:589
virtual void set_tolerances(double r_tol, double a_tol, unsigned int max_it)=0
virtual void apply_constrains(double scalar)=0
static constexpr bool value
Definition: json.hpp:87
bool is_preallocated()
Definition: linsys.hh:546
void mat_set_value(int row, int col, double val)
Definition: linsys.hh:326
#define OLD_ASSERT(...)
Definition: global_defs.h:131
Global macros to enhance readability and debugging, general constants.
virtual PetscErrorCode set_rhs(Vec &rhs)
Definition: linsys.hh:231
MPI_Comm comm_
Definition: linsys.hh:606
double get_relative_accuracy()
Definition: linsys.hh:484
unsigned int max_it_
maximum number of iterations of linear solver
Definition: linsys.hh:604
double * get_solution_array()
Definition: linsys.hh:282
const Vec & get_solution()
Definition: linsys.hh:258
static constexpr unsigned int default_max_it_
Definition: linsys.hh:600
Accessor to the data with type Type::Record.
Definition: accessors.hh:286
const Distribution * rows_ds_
final distribution of rows of MH matrix
Definition: linsys.hh:612
double a_tol_
absolute tolerance of linear solver
Definition: linsys.hh:603
SetValuesMode
Definition: linsys.hh:81
static constexpr double default_a_tol_
Definition: linsys.hh:599
double residual_norm_
local solution array pointing into Vec solution_
Definition: linsys.hh:626
bool is_rhs_changed()
Definition: linsys.hh:215
bool negative_definite_
Definition: linsys.hh:616
void set_solution(double *sol_array)
Definition: linsys.hh:266
Class for declaration of polymorphic Record.
virtual const Vec * get_rhs()
Definition: linsys.hh:179
virtual PetscErrorCode rhs_zero_entries()
Definition: linsys.hh:249
bool is_symmetric()
Definition: linsys.hh:507
Support classes for parallel programing.
#define MPI_Allreduce(sendbuf, recvbuf, count, datatype, op, comm)
Definition: mpi.h:612
std::vector< Constraint_ > ConstraintVec_
Definition: linsys.hh:91
arma::mat matrix
local system matrix
void set_values(int nrow, int *rows, int ncol, int *cols, PetscScalar *mat_vals, PetscScalar *rhs_vals)
Set values in the system matrix and values in the right-hand side vector on corresponding rows...
Definition: linsys.hh:343
double r_tol_
relative tolerance of linear solver
Definition: linsys.hh:602
#define MPI_INT
Definition: mpi.h:160
Abstract linear system class.
bool is_positive_definite()
Definition: linsys.hh:534
void set_matrix_changed()
Definition: linsys.hh:188
void set_positive_definite(bool flag=true)
Definition: linsys.hh:513
virtual PetscErrorCode set_matrix(Mat &matrix, MatStructure str)
Definition: linsys.hh:222
static Input::Type::Abstract & get_input_type()
Definition: linsys.cc:29
virtual void mat_set_values(int nrow, int *rows, int ncol, int *cols, double *vals)=0
bool positive_definite_
Definition: linsys.hh:615
bool own_solution_
Indicates if the solution array has been allocated by this class.
Definition: linsys.hh:624
virtual const Mat * get_matrix()
Definition: linsys.hh:163
virtual double get_absolute_accuracy()
Definition: linsys.hh:491
virtual double compute_residual()=0
Vec solution_
PETSc vector constructed with vb array.
Definition: linsys.hh:622
LinSys(LinSys &other)
Definition: linsys.hh:123
bool is_spd_via_symmetric_general()
Definition: linsys.hh:562
virtual int solve()=0
void eliminate_solution()
void rhs_set_value(int row, double val)
Definition: linsys.hh:338
DofVec row_dofs
Definition: local_system.hh:36
unsigned int lsize(int proc) const
get local size