Flow123d
linsys_proposed.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2007 Technical University of Liberec. All rights reserved.
4  *
5  * Please make a following refer to Flow123d on your project site if you use the program for any purpose,
6  * especially for academic research:
7  * Flow123d, Research Centre: Advanced Remedial Technologies, Technical University of Liberec, Czech Republic
8  *
9  * This program is free software; you can redistribute it and/or modify it under the terms
10  * of the GNU General Public License version 3 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along with this program; if not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 021110-1307, USA.
18  *
19  *
20  * $Id: la_linsys.hh 1299 2011-08-23 21:42:50Z jakub.sistek $
21  * $Revision: 1299 $
22  * $LastChangedBy: jakub.sistek $
23  * $LastChangedDate: 2011-08-23 23:42:50 +0200 (Tue, 23 Aug 2011) $
24  *
25  * @file
26  * @brief Wrappers for linear systems based on MPIAIJ and MATIS format.
27  * @author Jan Brezina
28  *
29  * Linear system only keep together matrix, RHS and the solution vector.
30  *
31  */
32 
33 
34 //=============================================================================
35 //
36 // LINER SYSTEM ROUTINES - linear system use wrapers of PETSc assembling routins
37 // in order to allow counting of allocation and filling of matrix to be done by the same code
38 //
39 // we want to allow allocations of nonlocal rows, to this end we count on- and off-processor
40 // members in an parallel Vector
41 //
42 //=============================================================================
43 
44 #ifndef LA_LINSYS_HH_
45 #define LA_LINSYS_HH_
46 
47 #include "petscmat.h"
48 #include "private/matimpl.h"
49 
50 //#include "la/schur.hh"
51 #include "la/distribution.hh"
52 
53 
54 /**
55  * @brief Abstract linear system class.
56  *
57  * Linear system consists of Matrix, RHS and solution.
58  * It provides general methods for:
59  * - matrix preallocation
60  * - assembling matrix and RHS
61  * - application of linear constrains (Dirichlet conditions) either during assembly or
62  * on assembled system
63  * - solution of the system
64  * - output in Matlab format
65  *
66  * Method operates on the system as single object. But some methods for matrix only manipulation
67  * can be provided until we have matrix as separate class.
68  */
69 
70 class LinSys
71 {
72 public:
73  typedef enum {
74  INSERT=INSERT_VALUES,
75  ADD=ADD_VALUES,
76  ALLOCATE,
77  DONE,
78  NONE
79  } SetValuesMode;
80 
81  typedef enum {
85  PETSC_schur_complement // possibly we can implement Schur as another kind of lin solver
86  } LinSysType;
87 
88  /**
89  * Constructor.
90  * Constructor of abstract class should not be called directly, but is used for initialization of member common
91  * to all particular solvers.
92  *
93  * @param lsize - local size of the solution vector
94  * @param sol_array - optionally one can provide pointer to array allocated to size lsize, where
95  * the solution should be stored,
96  */
97  LinSys(unsigned int lsize, double *sol_array = NULL);
98 
99  /// Particular type of the linear system.
100  LinSysType type; ///< MAT_IS or MAT_MPIAIJ anyone can inquire my type
101 
102 
103  /**
104  * Returns global system size.
105  */
106  inline unsigned int size()
107  { return vec_ds.size(); }
108 
109  /**
110  * Returns local system size. (for partitioning of solution vectors)
111  * for PETSC_MPIAIJ it is also partitioning of the matrix
112  */
113  inline unsigned int vec_lsize()
114  { return vec_ds.lsize(); }
115 
116  /**
117  * Returns whole Distribution class for distribution of the solution.
118  */
119  inline const Distribution &ds()
120  { return vec_ds; }
121 
122  /**
123  * Returns PETSC matrix (only for PETSC solvers)
124  */
125  inline const Mat &get_matrix()
126  { return matrix; }
127 
128  /**
129  * Returns RHS vector (only for PETSC solvers)
130  */
131  inline const Vec &get_rhs()
132  { return rhs; }
133 
134  /**
135  * Returns PETSC vector with solution. Underlying array can be provided on construction.
136  * Can this be implemented for BDDC?
137  */
138  inline const Vec &get_solution()
139  { return solution; }
140 
141  /**
142  * Returns local part of solution vector.
143  * Can this be implemented for BDDC?
144  */
145  inline double *get_solution_array()
146  { return v_solution; }
147 
148  /**
149  * Switch linear system into allocating assembly. (only for PETSC_MPIAIJ_preallocate_by_assembly)
150  */
151  virtual void start_allocation()=0;
152 
153  /**
154  * Switch linear system into adding assembly. (the only one supported by triplets ??)
155  */
156  void start_add_assembly();
157  /**
158  * Switch linear system into insert assembly. (not currently used)
159  */
160  void start_insert_assembly();
161 
162 
163  /**
164  * May not be necessary. For PETSC this should call MatEndAssembly with MAT_PARTIAL_ASSEMBLY
165  */
166  void partial_assembly();
167  /**
168  * Finish assembly of the whole system. For PETSC this should call MatEndAssembly with MAT_FINAL_ASSEMBLY
169  */
170  void finish_assembly();
171 
172  /**
173  * Assembly full rectangular submatrix into the system matrix.
174  * Should be virtual, implemented differently in particular solvers.
175  */
176  virtual void mat_set_values(int nrow,int *rows,int ncol,int *cols,PetscScalar *vals) = 0;
177 
178 
179  /**
180  * Shortcut for assembling just one element into the matrix.
181  * Similarly we can provide method accepting armadillo matrices.
182  */
183  inline void mat_set_value(int row,int col,PetscScalar val)
184  { mat_set_values(1,&row,1,&col,&val); }
185 
186  /**
187  * Set values of the system right-hand side.
188  * Should be virtual, implemented differently in particular solvers.
189  */
190  inline void rhs_set_values(int nrow,int *rows,PetscScalar *vals)
191  {
192  switch (status) {
193  case INSERT:
194  case ADD:
195  VecSetValues(rhs,nrow,rows,vals,(InsertMode)status); break;
196  case ALLOCATE: break;
197  default: ASSERT(0, "LinSys's status disallow set values.\n");
198  }
199  }
200 
201  /**
202  * Shorcut for assembling just one element into RHS vector.
203  */
204  inline void rhs_set_value(int row,PetscScalar val)
205  { rhs_set_values(1,&row,&val); }
206 
207  /**
208  * Shortcut to assembly into matrix and RHS in one call.
209  * This can also apply constrains at assembly time (only in add assembly regime).
210  *
211  * Constrains can either be set before through add_constrain. Or by additional parameters if we
212  * have only per element knowledge about boundary conditions.
213  *
214  */
215  inline void set_values(int nrow,int *rows,int ncol,int *cols,PetscScalar *mat_vals, PetscScalar *rhs_vals,
216  std::vector<bool> &constrains_row_mask=std::vector(0), double * constrain_values=NULL)
217  {
218  mat_set_values(nrow, rows, ncol, cols, mat_vals);
219  rhs_set_values(nrow, rows, rhs_vals);
220  }
221 
222  /**
223  * Adds Dirichlet constrain.
224  * @param row - global numeb of row that should be eliminated.
225  * @param value - solution value at the given row
226  */
227  void add_constrain(int row, double value);
228 
229  /**
230  * Apply constrains to assembled matrix. Constrains are given by pairs: global row index, value.
231  * i.e. typedef pair<unsigned int, double> Constrain;
232  *
233  * What is th meaning of ( const double factor ) form Cambridge code?
234  */
235 
236  void apply_constrains(std::vector<Constrain> & constraints);
237 
238 
239  /**
240  * Solve the system.
241  *
242  * parameters should by provided in input file (currently INI file, but will be changed to JSON)
243  *
244  * If we realize that we need to set something, rather add some set_* function.
245  *
246  * double tol = 1.e-7, //!< tolerance on relative residual ||res||/||rhs||
247  int numLevels = 2, //!< number of levels
248  std::vector<int> * numSubAtLevels = NULL, //!< number of subdomains at levels
249  int verboseLevel = 0, //!< level of verbosity of BDDCML library
250  //!< ( 0 - only fatal errors reported,
251  //!< 1 - mild output,
252  //!< 2 - detailed output )
253  int maxIt = 1000, //!< maximum number of iterations
254  int ndecrMax = 30 ); //!< maximum number of iterations with non-decreasing residual
255  //!< ( used to stop diverging process )
256  *
257  *
258  * Returns convergence reason (form PETSC)
259  */
260  virtual int solve();
261 
262 
263  /**
264  * Provides user knowledge about symmetry.
265  */
266  inline void set_symmetric(bool flag = true)
267  {
268  symmetric = flag;
269  if (!flag) set_positive_definite(false);
270  }
271 
272  inline bool is_symmetric()
273  { return symmetric; }
274 
275  /**
276  * Provides user knowledge about positive definiteness.
277  */
278  inline void set_positive_definite(bool flag = true)
279  {
280  positive_definite = flag;
281  if (flag) set_symmetric();
282  }
283 
284  inline bool is_positive_definite()
285  { return positive_definite; }
286 
287 
288  /**
289  * Output the system in the Matlab format possibly with given ordering.
290  * Rather we shoud provide output operator <<, since it is more flexible.
291  */
292  void view(std::ostream output_stream, int * output_mapping = NULL);
293 
294  virtual ~LinSys();
295 
296 protected:
297  /**
298  * Protected methods used in preallocate_by_assembly solvers.
299  */
300  virtual void preallocate_matrix()=0;
301  /**
302  * Protected methods used in preallocate_by_assembly solvers.
303  */
304  virtual void preallocate_values(int nrow,int *rows,int ncol,int *cols)=0;
305 
306 
307  Distribution vec_ds; ///< Distribution of continuous blocks of system rows among the processors.
308  bool symmetric; ///< Flag for the symmetric system.
309  bool positive_definite; ///< Flag for positive definite system.
310  bool own_solution; ///< Indicates if the solution array has been allocated by this class.
311  SetValuesMode status; ///< Set value status of the linear system.
312 
313  Mat matrix; ///< Petsc matrix of the problem.
314  Vec rhs; ///< PETSc vector constructed with vx array.
315  Vec solution; ///< PETSc vector constructed with vb array.
316  double *v_rhs; ///< RHS vector.
317  double *v_solution; ///< Vector of solution.
318 
319  // for MATIS
320  int *subdomain_indices; ///< Remember indices which created mapping
321  Mat local_matrix; ///< local matrix of subdomain (used in LinSys_MATIS)
322 
323  friend void SchurComplement::form_schur();
324  friend class SchurComplement;
325 };
326 
327 
328 
329 class LinSys_MPIAIJ : public LinSys
330 {
331 public:
332  LinSys_MPIAIJ(unsigned int lsize, double *sol_array=NULL) : LinSys(lsize, sol_array) {};
333  virtual void start_allocation();
334  virtual void preallocate_matrix();
335  virtual void preallocate_values(int nrow,int *rows,int ncol,int *cols);
336  virtual void view_local_matrix();
337  virtual ~LinSys_MPIAIJ();
338 
339 private:
340 
341  Vec on_vec,off_vec; ///< Vectors for counting non-zero entries.
342 
343 };
344 
345 
346 class LinSys_MATIS : public LinSys
347 {
348 public:
349  LinSys_MATIS(unsigned int lsize, int sz, int *global_row_4_sub_row, double *sol_array=NULL);
350  virtual void start_allocation();
351  virtual void preallocate_matrix();
352  virtual void preallocate_values(int nrow,int *rows,int ncol,int *cols);
353  virtual void view_local_matrix();
354 
355  inline VecScatter get_scatter()
356  { return sub_scatter; }
357  /// Get local subdomain size.
358  inline int get_subdomain_size()
359  { return subdomain_size; }
360 
361  virtual ~LinSys_MATIS();
362 
363 private:
364 
365  ISLocalToGlobalMapping map_local_to_global; ///< PETSC mapping form local indexes of subdomain to global indexes
366  int loc_rows_size; ///<
367  int *loc_rows; ///< Small auxiliary array for translation of global indexes to local
368  ///< during preallocate_set_values. However for MatSetValues
369  VecScatter sub_scatter; ///< from global vector with no overlaps constructs local (subdomain)
370  ///< vectors with overlaps
371  ///< copy of scatter created and used in PETSc in Mat_IS
372 
373  int subdomain_size; ///< size of subdomain in MATIS matrix
374  int *subdomain_nz; ///< For counting non-zero enteries of local subdomain.
375 
376  // mimic PETSc struct for IS matrices - included from matis.h
377  // used to access private PETSc data
378  typedef struct {
379  Mat A; /* the local Neumann matrix */
380  VecScatter ctx; /* update ghost points for matrix vector product */
381  Vec x,y; /* work space for ghost values for matrix vector product */
382  ISLocalToGlobalMapping mapping;
383  int rstart,rend; /* local row ownership */
384  PetscTruth pure_neumann;
385  } MatMyIS ;
386 };
387 
388 
389 
390 #endif /* LA_LINSYS_HH_ */