Flow123d
bddcml_wrapper.hpp
Go to the documentation of this file.
1 //! @author Jakub Sistek
2 //! @date 5/2011
3 
4 #ifndef la_bddcml_wrapper_h
5 #define la_bddcml_wrapper_h
6 //------------------------------------------------------------------------------
7 #include <boost/numeric/ublas/matrix.hpp>
8 #include <boost/numeric/ublas/vector.hpp>
9 #include <ostream>
10 #include <vector>
11 #include <set>
12 #include <cmath>
13 #include <la/matrix_coo.hpp>
14 
15 #include <system/global_defs.h>
16 #include <system/xio.h>
17 
18 extern "C" {
19  #include <bddcml_interface_c.h>
20 }
21 
22 //------------------------------------------------------------------------------
23 namespace la{
24  class BddcmlWrapper;
25  namespace ublas = boost::numeric::ublas;
26 
27  namespace detail_{
28 
29  template< typename NODE, typename MAPTYPE >
30  int getLocalNumber( NODE * np, MAPTYPE & map ) {
31 
32  unsigned globalIndex = np -> giveId( );
33 
34  typename MAPTYPE::iterator pos = map.find( globalIndex );
35  ASSERT( pos != map.end(),
36  "Cannot remap node index %d to local indices. \n ", globalIndex );
37  int localIndexInt = pos -> second;
38 
39  return localIndexInt;
40  }
41  }
42 
43 }
44 
45 //------------------------------------------------------------------------------
46 /** \brief Multilevel BDDC based linear system solver
47  * \details This class implements solution of a system of linear equations
48  * by multilevel BDDC implementation in BDDCML solver.
49  *
50  * The class uses assembly of the matrix into
51  * the coordinate matrix format implemented in matrix_coo.hpp file.
52  *
53  * prepareMatAssembly - (optional) - reserves memory for sparse coordinate matrix
54  * insertToMatrix - called many times, inserts values into coordinate matrix
55  * insertToRhs - called many times, inserts values into RHS.
56  * If matrix is created and assembled, structure of the vector is deduced from it.
57  * Otherwise, it is created as empty.
58  * applyConstraints - currently only passes list of boundary conditions into the BDDCML solver,
59  * rather then modifying the matrix and rhs
60  * - as a result, no nonsymmetry is forced to SPD and symmetric indefinite problems by constraints,
61  * and these can be accelerated and be more memory efficient by specifying proper matrixType
62  * solveSystem - solves the system
63  */
65 {
66 public:
68  GENERAL, //!< general (default),
69  SPD, //!< symmetric positive definite,
70  SYMMETRICGENERAL, //!< general symmetric ( e.g. saddle point ),
71  SPD_VIA_SYMMETRICGENERAL //!< (advanced) interface problem is symm. pos. def.,
72  //!< but subdomain problems are general symmetric ( e.g. saddle point )
73  };
74  typedef enum matrixTypeEnum MatrixType;
75 
76 private:
77  typedef ublas::matrix< double > SubMat_;
78  typedef ublas::vector< double > SubVec_;
81 
82 public:
83  //! Constructor with
84  //! total number of dofs,
85  //! subdomain number of dofs,
86  //! (optional) type of matrix,
87  //! (optional) communicator ( MPI_COMM_WORLD is the default ),
88  //! (optional) number of subdomains ( if not given, use number of processes ),
89  BddcmlWrapper( const unsigned numDofs,
90  const unsigned numDofsSub,
91  const MatrixType matrixType = GENERAL,
92  const MPI_Comm comm = MPI_COMM_WORLD,
93  int numSubLoc = 1 );
94 
95  //! Destructor frees the BDDCML structures
97 
98  //! Load raw data about mesh
99  void loadRawMesh( const int nDim, const int numNodes, const int numDofs,
100  const std::vector<int> & inet,
101  const std::vector<int> & nnet,
102  const std::vector<int> & nndf,
103  const std::vector<int> & isegn,
104  const std::vector<int> & isngn,
105  const std::vector<int> & isvgvn,
106  const std::vector<double> & xyz,
107  const std::vector<double> & element_data,
108  const int meshDim = 0 );
109 
110  void loadDiagonal( std::map<int,double> & diag );
111 
112  //! Prepare assembly of matrix - reserve space in underlying coordinate matrix object
113  void prepareMatAssembly( unsigned numElements, unsigned elMatSize );
114 
115  //! insert submatrix to system matrix - into coordinate matrix object
116  void insertToMatrix( const SubMat_ & eStiff,
117  const VecUint_ & rowIndices,
118  const VecUint_ & colIndices );
119 
120  //! Finalize assembly of matrix
121  void finishMatAssembly( );
122 
123  //! insert subvector to system rhs vector
124  void insertToRhs( const SubVec_ & eForce, const VecUint_ & dofIndices );
125 
126  //! Outputs
127  void writeMatrix( std::ostream & out ) { coo_.write( out ); }
128 
129  //! Compatibility call which does absolutely nothing
130  void finishAssembly( ) { }
131 
132  //! Apply constraints
133  //! Currently, scalar is not used in the function and it is kept only for compatibility with constraint functors.
134  //! Proper scalar is enforced within the BDDC solver.
135  void applyConstraints( ConstraintVec_ & constraints, const double factor, const double scalar );
136 
137  //! Set any DOF to zero
138  //!
139  //! \param[in] index Global index of DOF to fix
140  //! \param[in] scalar Value to put on diagonal (default 1.)
141  void fixDOF( const unsigned index, const double scalar = 1. );
142 
143  //! Solve the system
144  void solveSystem( double tol = 1.e-7, //!< tolerance on relative residual ||res||/||rhs||
145  int numLevels = 2, //!< number of levels
146  std::vector<int> * numSubAtLevels = NULL, //!< number of subdomains at levels
147  int verboseLevel = 0, //!< level of verbosity of BDDCML library
148  //!< ( 0 - only fatal errors reported,
149  //!< 1 - mild output,
150  //!< 2 - detailed output )
151  int maxIt = 1000, //!< maximum number of iterations
152  int ndecrMax = 30, //!< maximum number of iterations with non-decreasing residual
153  //!< ( used to stop diverging process )
154  bool use_adaptive = false //!< if adaptive constraints should be used by BDDCML
155  );
156 
157  //! Get norm of right-hand side
158  double normRhs( ) { return normRhs_; }
159 
160  //! Get norm of solution
161  double normSol( ) { return normSol_; }
162 
163  //! Give number of iteration
164  int giveNumIterations() { return numIter_ ; }
165 
166  //! Give reason of convergence
168 
169  //! Give estimate of condition number
170  double giveCondNumber() { return condNumber_ ; }
171 
172  //! Fill matrix with zeros
173  void clearMatrix( ) {
174  // remember length
175  unsigned length = coo_.nnz( );
176  coo_.clear( );
177  coo_.prepareAssembly( length );
178  }
179  //! Fill RHS with zeros
180  void clearRhs( ) {
181  std::fill( rhsVec_.begin( ), rhsVec_.end( ), 0. );
182  normRhs_ = 0.;
183  }
184 
185  //! Blank arrays for boundary conditions
186  void clearBC( ) {
187  std::fill( ifix_.begin(), ifix_.end(), 0 );
188  std::fill( fixv_.begin(), fixv_.end(), 0. );
189  }
190 
191  //! Fill solution with zeros
192  void clearSol( )
193  { std::fill( sol_.begin( ), sol_.end( ), 0. );
194  normSol_ = 0.;
195  }
196 
197  //! Destroy matrix
198  void destroyMatrix( ) {
199  coo_.clear( );
200  }
201  //! Destroy RHS
202  void destroyRhs( ) { rhsVec_.clear( ); }
203  //! Destroy boundary conditions
204  void destroyBC( ) {
205  ifix_.clear( );
206  fixv_.clear( );
207  }
208  //! Destroy solution
209  void destroySol( ) { sol_.clear( ); }
210 
211  //! Give access to the solution vector
212  template<typename VEC1,typename VEC2>
213  void giveSolution( const VEC1 & dofIndices, VEC2 & result ) const;
214 
215 private:
216  const int numDofs_; //!< number of total dofs
217  const int numDofsSub_; //!< number of subdomain dofs
218  const MatrixType matrixType_; //!< type of matrix
219  const MPI_Comm comm_; //!< communicator
220  int numSubLoc_; //!< number of subdomains on process
221 
222  int nProc_; //!< number of processors in communicator
223  int rank_; //!< ID of processors in communicator
224 
225  int nDim_; //!< space dimension
226  int meshDim_; //!< mesh dimension, may differ from space dimension - e.g. 2 for shells in 3D
227 
228  int numElemSub_; //!< number of elements in subdomain
229  int numElem_; //!< total number of elements
230  int numNodesSub_; //!< number of nodes in subdomain
231  int numNodes_; //!< total number of nodes
232 
233  bool meshLoaded_; //! safety state variable to warn if solver is called without loading subdomain mesh
234  std::vector<int> inet_; //!< indices of nodes on elements (linearized connectivity) - numbering w.r.t. local subdomain numbering
235  std::vector<int> nnet_; //!< numbers of nodes on elements
236  //!< (determines chunks of nodes for each element in inet),
237  //!< e.g. [ 8, 8, 8, ... ] for linear hexahedra
238  std::vector<int> nndf_; //!< number of nodal degrees of freedom ( entry for each node ),
239  //!< e.g. [ 3, 3, 3, ... ] for 3D solids
240  std::vector<double> xyz_; //!< linearized array of coordinates - all x values, all y values, all z values ( if present )
241  //!< i.e. [ x_0 x_1 x_2 ... x_(numNodes - 1) y_0 y_1 y_2 ... y_(numNodes - 1) z_0 z_1 z_2 ... z_(numNodes - 1) ]
242  std::vector<double> element_data_; //!< array with data on elements, here used for permeability for each element
243 
244  std::vector<int> isngn_; //!< Indices of Subdomain Nodes in Global Numbering
245  std::vector<int> isvgvn_; //!< Indices of Subdomain Variables in Global Variable Numbering ( i.e. dof mapping )
246  std::vector<int> isegn_; //!< Indices of Subdomain Elements in Global Numbering
247 
248  typedef std::map<unsigned,unsigned> Global2LocalMap_; //! type for storage of global to local map
249  Global2LocalMap_ global2LocalDofMap_; //!< map from global dof indices to subdomain local indices
250 
251 
252  std::vector<int> ifix_; //!< indices of fixed boundary conditions - ( 0 for free variable, 1 for constrained dof )
253  std::vector<double> fixv_; //!< values of fixed boundary conditions at places of ifix_ - values outside fixed dofs are ignored
254 
255  la::MatrixCoo<int,double> coo_; //!< matrix in coordinate format (COO)
256  bool isMatAssembled_; //!< true if matrix is assembled
257  std::map<int,double> diag_; //!< diagonal of subdomain matrix in sparse format and global numbers
258 
259  std::vector<double> rhsVec_; //!< vector with RHS values restricted to subdomain, i.e. values are repeated at shared nodes
260  double normRhs_; //!< norm of the global right-hand side
261 
262  std::vector<double> sol_; //!< distributed solution vector
263  double normSol_; //!< norm of the global solution
264 
265  int numIter_; //!< required number of iterations
266  int convergedReason_; //!< reason of convergence:
267  //!< 0 - converged relative residual, desirable state
268  //!< -1 - reached maximal number of iterations
269  //!< -2 - reached maximal number of iterations with non-decreasing residual
270  double condNumber_; //!< estimated condition number of the preconditioned operator
271  //!< only provided for SPD problems solved by PCG ( -1.0 if not meaningful )
272 
273 };
274 
275 //-----------------------------------------------------------------------------
276 
277 #include "bddcml_wrapper.ipp"
278 
279 //-----------------------------------------------------------------------------
280 
281 #endif