ug4
ilut.h
Go to the documentation of this file.
1 
2 #ifndef __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__ILUT__
3 #define __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__ILUT__
4 
7 #ifdef UG_PARALLEL
9 #endif
10 #include "common/progress.h"
13 
15 
17 #include "lib_algebra/ordering_strategies/algorithms/native_cuthill_mckee.h" // for backward compatibility
18 
20 
21 namespace ug{
22 
23 template <typename TAlgebra>
24 class ILUTPreconditioner : public IPreconditioner<TAlgebra>
25 {
26  public:
27  // Algebra type
28  typedef TAlgebra algebra_type;
29 
30  // Vector type
31  typedef typename TAlgebra::vector_type vector_type;
33 
34  // Matrix type
35  typedef typename TAlgebra::matrix_type matrix_type;
36 
37  typedef typename matrix_type::row_iterator matrix_row_iterator;
38  typedef typename matrix_type::const_row_iterator const_matrix_row_iterator;
39  typedef typename matrix_type::connection matrix_connection;
40 
42  typedef std::vector<size_t> ordering_container_type;
44 
48 
49  protected:
51 
54 
55  private:
57 
58  public:
60  ILUTPreconditioner(double eps=1e-6)
61  : m_eps(eps), m_info(false), m_show_progress(true), m_bSortIsIdentity(false)
62  {
63  //default was set true
65  };
66 
70  {
71  m_eps = parent.m_eps;
72  set_info(parent.m_info);
74  }
75 
78  {
79  return make_sp(new ILUTPreconditioner<algebra_type>(*this));
80  }
81 
82 
85  {};
86 
88  virtual bool supports_parallel() const {return true;}
89 
91  void set_threshold(number thresh)
92  {
93  m_eps = thresh;
94  }
95 
97  void set_info(bool info)
98  {
99  m_info = info;
100  }
101 
103  void set_show_progress(bool s)
104  {
105  m_show_progress = s;
106  }
107 
108  virtual std::string config_string() const
109  {
110  std::stringstream ss;
111  ss << "ILUT(threshold = " << m_eps << ", sort = " << (m_spOrderingAlgo.valid()?"true":"false") << ")";
112  if(m_eps == 0.0) ss << " = Sparse LU";
113  return ss.str();
114  }
115 
118  m_spOrderingAlgo = ordering_algo;
119  }
120 
122  void set_sort(bool b)
123  {
124  if(b){
126  }
127  else{
129  }
130 
131  UG_LOG("\nILUT: please use 'set_ordering_algorithm(..)' in the future\n");
132  }
133 
134 
135  protected:
136  // Name of preconditioner
137  virtual const char* name() const {return "ILUT";}
138 
139  protected:
141  const vector_type& u)
142  {
143  // cast to matrix based operator
145  J.template cast_dynamic<MatrixOperator<matrix_type, vector_type> >();
146 
147  // Check that matrix if of correct type
148  if(pOp.invalid())
149  UG_THROW(name() << "::init': Passed Operator is "
150  "not based on matrix. This Preconditioner can only "
151  "handle matrix-based operators.");
152 
153  m_u = &u;
154 
155  // forward request to matrix based implementation
156  return base_type::init(pOp);
157  }
158 
160  {
161  // cast to matrix based operator
163  L.template cast_dynamic<MatrixOperator<matrix_type, vector_type> >();
164 
165  // Check that matrix if of correct type
166  if(pOp.invalid())
167  UG_THROW(name() << "::init': Passed Operator is "
168  "not based on matrix. This Preconditioner can only "
169  "handle matrix-based operators.");
170 
171  m_u = NULL;
172 
173  // forward request to matrix based implementation
174  return base_type::init(pOp);
175  }
176 
178  {
179  m_u = NULL;
180 
181  return base_type::init(Op);
182  }
183 
184  // Preprocess routine
186  {
187  return preprocess_mat(*pOp);
188  }
189 
190  public:
191  virtual bool preprocess_mat(matrix_type &mat)
192  {
193 #ifdef UG_PARALLEL
194  matrix_type m2;
195  m2 = mat;
196 
198 
199  // set zero on slaves
200  std::vector<IndexLayout::Element> vIndex;
201  CollectUniqueElements(vIndex, mat.layouts()->slave());
202  SetDirichletRow(m2, vIndex);
203 
204  // Even after this setting of Dirichlet rows, it is possible that there are
205  // zero rows on a proc because of the distribution:
206  // For example, if one has a horizontal grid interface between two SHADOW_RIM_COPY
207  // vertices, but the shadowing element for the hSlave side is vMaster (without being in
208  // any horizontal interface). Then, as the horizontal interface (on the shadowed level)
209  // is not part of the algebraic layouts, the hSlave is not converted into a Dirichlet row
210  // by the previous commands.
211  // As a first aid, we will simply convert any zero row on the current proc into a
212  // Dirichlet row.
213  // TODO: The corresponding rhs vector entry could be non-zero!
214  // It is definitely not set to zero by change_storage_type(PST_UNIQUE) as the index is not contained
215  // in the vector layouts either. Still, the defect assembling process might contain a vertex
216  // loop and assemble something that is not solution-dependent! What do we do then?
217  size_t nInd = m2.num_rows();
218  size_t cnt = 0;
219  for (size_t i = 0; i < nInd; ++i)
220  {
221  if (!m2.num_connections(i))
222  {
223  m2(i,i) = 1.0;
224  ++cnt;
225  }
226  }
227 #ifndef NDEBUG
228  if (cnt) UG_LOG_ALL_PROCS("Converted "<<cnt<<" zero rows into Dirichlet rows.\n");
229 #endif
230 
231  return preprocess_mat2(m2);
232 #else
233  return preprocess_mat2(mat);
234 #endif
235  }
236 
237  virtual bool preprocess_mat2(matrix_type &mat)
238  {
239  PROFILE_BEGIN_GROUP(ILUT_preprocess, "ilut algebra");
240  //matrix_type &mat = *pOp;
241  STATIC_ASSERT(matrix_type::rows_sorted, Matrix_has_to_have_sorted_rows);
242  write_debug(mat, "ILUT_PreprocessIn");
243 
244  matrix_type* A;
245  matrix_type permA;
246 
247  if(m_spOrderingAlgo.valid()){
248  if(m_u){
249  m_spOrderingAlgo->init(&mat, *m_u);
250  }
251  else{
252  m_spOrderingAlgo->init(&mat);
253  }
254  }
255 
256  if(m_spOrderingAlgo.valid())
257  {
258  m_spOrderingAlgo->compute();
259  m_ordering = m_spOrderingAlgo->ordering();
260 
262 
263  if(!m_bSortIsIdentity){
264  SetMatrixAsPermutation(permA, mat, m_ordering);
265  A = &permA;
266  }
267  else{
268  A = &mat;
269  }
270  }
271  else
272  {
273  A = &mat;
274  }
275 
276  m_L.resize_and_clear(A->num_rows(), A->num_cols());
277  m_U.resize_and_clear(A->num_rows(), A->num_cols());
278 
279  size_t totalentries=0;
280  size_t maxentries=0;
281 
282  if((A->num_rows() > 0) && (A->num_cols() > 0)){
283  // con is the current line of L/U
284  // i also tried using std::list here or a special custom vector-based linked list
285  // but vector is fastest, even with the insert operation.
286  std::vector<matrix_connection> con;
287  con.reserve(300);
288  con.resize(0);
289 
290  // init row 0 of U
291  for(matrix_row_iterator i_it = A->begin_row(0); i_it != A->end_row(0); ++i_it)
292  con.push_back(matrix_connection(i_it.index(), i_it.value()));
293  m_U.set_matrix_row(0, &con[0], con.size());
294 
295  Progress prog;
296  if(m_show_progress)
297  PROGRESS_START_WITH(prog, A->num_rows(),
298  "Using ILUT(" << m_eps << ") on " << A->num_rows() << " x " << A->num_rows() << " matrix...");
299 
300  for(size_t i=1; i<A->num_rows(); i++)
301  {
302  if(m_show_progress) {PROGRESS_UPDATE(prog, i);}
303  con.resize(0);
304  size_t u_part=0;
305 
306  UG_COND_THROW(A->num_connections(i) == 0, "row " << i << " has no connections");
307 
308  // get the row A(i, .) into con
309  double dmax=0;
310  for(matrix_row_iterator i_it = A->begin_row(i); i_it != A->end_row(i); ++i_it)
311  {
312  con.push_back(matrix_connection(i_it.index(), i_it.value()));
313  if(dmax < BlockNorm(i_it.value()))
314  dmax = BlockNorm(i_it.value());
315  }
316 
317  // eliminate all entries A(i, k) with k<i with rows U(k, .) and k<i
318  for(size_t i_it = 0; i_it < con.size(); ++i_it)
319  {
320  size_t k = con[i_it].iIndex;
321  if(k >= i)
322  {
323  // safe where U begins / L ends in con
324  u_part = i_it;
325  break;
326  }
327  if(con[i_it].dValue == 0.0) continue;
328  UG_COND_THROW(!(m_U.num_connections(k) != 0 && m_U.begin_row(k).index() == k), "");
329  block_type &ukk = m_U.begin_row(k).value();
330 
331  // add row k to row i by A(i, .) -= U(k,.) A(i,k) / U(k,k)
332  // so that A(i,k) is zero.
333  // safe A(i,k)/U(k,k) in con, (later L(i,k) )
334  con[i_it].dValue = con[i_it].dValue / ukk;
335  block_type d = con[i_it].dValue;
336  UG_COND_THROW(!BlockMatrixFiniteAndNotTooBig(d, 1e40), "i = " << i << " " << d);
337 
338  matrix_row_iterator k_it = m_U.begin_row(k); // upper row iterator
339  ++k_it; // skip diag
340  size_t j = i_it+1;
341  while(k_it != m_U.end_row(k) && j < con.size())
342  {
343  // (since con and U[k] is sorted, we can do sth like a merge on the two lists)
344  if(k_it.index() == con[j].iIndex)
345  {
346  // match
347  con[j].dValue -= k_it.value() * d;
348  ++k_it; ++j;
349  }
350  else if(k_it.index() < con[j].iIndex)
351  {
352  // we have a value in U(k, (*k_it).iIndex), but not in A.
353  // check tolerance criteria
354 
355  matrix_connection c(k_it.index(), k_it.value() * d * -1.0);
356 
357  UG_COND_THROW(!BlockMatrixFiniteAndNotTooBig(c.dValue, 1e40), "i = " << i << " " << c.dValue);
358  if(BlockNorm(c.dValue) > dmax * m_eps)
359  {
360  // insert sorted
361  con.insert(con.begin()+j, c);
362  ++j; // don't do this when using iterators
363  }
364  // else do some lumping
365  ++k_it;
366  }
367  else
368  {
369  // we have a value in A(k, con[j].iIndex), but not in U.
370  ++j;
371  }
372  }
373  // insert new connections after last connection of row i
374  if (k_it!=m_U.end_row(k)){
375  for (;k_it!=m_U.end_row(k);++k_it){
376  matrix_connection c(k_it.index(),-k_it.value()*d);
377  if(BlockNorm(c.dValue) > dmax * m_eps)
378  {
379  con.push_back(c);
380  }
381  }
382  };
383  }
384 
385 
386  totalentries+=con.size();
387  if(maxentries < con.size()) maxentries = con.size();
388 
389  // safe L and U
390  m_L.set_matrix_row(i, &con[0], u_part);
391  m_U.set_matrix_row(i, &con[u_part], con.size()-u_part);
392 
393  }
394  if(m_show_progress) {PROGRESS_FINISH(prog);}
395 
396  m_L.defragment();
397  m_U.defragment();
398  }
399 
400  if (m_info==true)
401  {
402  m_L.print("L");
403  m_U.print("U");
404  UG_LOG("\n ILUT storage information:\n");
405  UG_LOG(" A is " << A->num_rows() << " x " << A->num_cols() << " matrix.\n");
406  UG_LOG(" A nr of connections: " << A->total_num_connections() << "\n");
407  UG_LOG(" L+U nr of connections: " << m_L.total_num_connections()+m_U.total_num_connections() << "\n");
408  UG_LOG(" Increase factor: " << (float)(m_L.total_num_connections() + m_U.total_num_connections() )/A->total_num_connections() << "\n");
409  UG_LOG(reset_floats << " Total entries: " << totalentries << " (" << ((double)totalentries) / (A->num_rows()*A->num_rows()) << "% of dense)\n");
410  if(m_spOrderingAlgo.valid())
411  {
412  UG_LOG(" Using " << m_spOrderingAlgo->name() << "\n");
413  }
414  else
415  {
416  UG_LOG("Not using sort.");
417  }
418  }
419 
420  return true;
421  }
422 
423  // Stepping routine
425  {
426 #ifdef UG_PARALLEL
427  SmartPtr<vector_type> spDtmp = d.clone();
428  spDtmp->change_storage_type(PST_UNIQUE);
429  bool b = solve(c, *spDtmp);
430 
431  c.set_storage_type(PST_ADDITIVE);
432  c.change_storage_type(PST_CONSISTENT);
433  return b;
434 #else
435  return solve(c, d);
436 #endif
437  return true;
438  }
439 
440  virtual bool solve(vector_type& c, const vector_type& d)
441  {
442  if(m_spOrderingAlgo.invalid()|| m_bSortIsIdentity)
443  {
444  if(applyLU(c, d) == false) return false;
445  }
446  else
447  {
448  PROFILE_BEGIN_GROUP(ILUT_StepWithReorder, "ilut algebra");
449 
451  c2.resize(c.size());
452  if(applyLU(c2, c) == false) return false;
454  }
455  return true;
456  }
457 
458 
459  virtual bool applyLU(vector_type& c, const vector_type& d)
460  {
461  PROFILE_BEGIN_GROUP(ILUT_step, "ilut algebra");
462  // apply iterator: c = LU^{-1}*d (damp is not used)
463  // L
464  for(size_t i=0; i < m_L.num_rows(); i++)
465  {
466  // c[i] = d[i] - m_L[i]*c;
467  c[i] = d[i];
468  for(matrix_row_iterator it = m_L.begin_row(i); it != m_L.end_row(i); ++it)
469  MatMultAdd(c[i], 1.0, c[i], -1.0, it.value(), c[it.index()] );
470  // lii = 1.0.
471  }
472 
473  // U
474  //
475  // last row diagonal U entry might be close to zero with corresponding zero rhs
476  // when solving Navier Stokes system, therefore handle separately
477  if(m_U.num_rows() > 0)
478  {
479  size_t i=m_U.num_rows()-1;
480  matrix_row_iterator it = m_U.begin_row(i);
481  UG_ASSERT(it != m_U.end_row(i), i);
482  UG_ASSERT(it.index() == i, i);
483  block_type &uii = it.value();
484  vector_value s = c[i];
485  // check if diag part is significantly smaller than rhs
486  // This may happen when matrix is indefinite with one eigenvalue
487  // zero. In that case, the factorization on the last row is
488  // nearly zero due to round-off errors. In order to allow ill-
489  // scaled matrices (i.e. small matrix entries row-wise) this
490  // is compared to the rhs, that is small in this case as well.
491  if (false && BlockNorm(uii) <= m_small * m_eps * BlockNorm(s)){
492  UG_LOG("ILUT("<<m_eps<<") Warning: Near-zero diagonal entry "
493  "with norm "<<BlockNorm(uii)<<" in last row of U "
494  " with corresponding non-near-zero rhs with norm "
495  << BlockNorm(s) << ". Setting rhs to zero.\n");
496  // set correction to zero
497  c[i] = 0;
498  } else {
499  // c[i] = s/uii;
500  InverseMatMult(c[i], 1.0, uii, s);
501  }
502  }
503 
504  // handle all other rows
505  if(m_U.num_rows() > 1){
506  for(size_t i=m_U.num_rows()-2; ; i--)
507  {
508  matrix_row_iterator it = m_U.begin_row(i);
509  UG_ASSERT(it != m_U.end_row(i), i);
510  UG_ASSERT(it.index() == i, i);
511  block_type &uii = it.value();
512 
513  vector_value s = c[i];
514  ++it; // skip diag
515  for(; it != m_U.end_row(i); ++it){
516  // s -= it.value() * c[it.index()];
517  MatMultAdd(s, 1.0, s, -1.0, it.value(), c[it.index()] );
518  }
519  // c[i] = s/uii;
520  InverseMatMult(c[i], 1.0, uii, s);
521 
522  if(i==0) break;
523  }
524  }
525  return true;
526  }
527 
528  virtual bool multi_apply(std::vector<vector_type> &vc, const std::vector<vector_type> &vd)
529  {
530  PROFILE_BEGIN_GROUP(ILUT_step, "ilut algebra");
531  // apply iterator: c = LU^{-1}*d (damp is not used)
532  // L
533  for(size_t i=0; i < m_L.num_rows(); i++)
534  {
535 
536  for(size_t e=0; e<vc.size(); e++)
537  {
538  vector_type &c = vc[e];
539  const vector_type &d = vd[e];
540  // c[i] = d[i] - m_L[i]*c;
541  c[i] = d[i];
542  for(matrix_row_iterator it = m_L.begin_row(i); it != m_L.end_row(i); ++it)
543  MatMultAdd(c[i], 1.0, c[i], -1.0, it.value(), c[it.index()] );
544  // lii = 1.0.
545  }
546  }
547 
548  // U
549  //
550  // last row diagonal U entry might be close to zero with corresponding zero rhs
551  // when solving Navier Stokes system, therefore handle separately
552  if(m_U.num_rows() > 0)
553  {
554  for(size_t e=0; e<vc.size(); e++)
555  {
556  vector_type &c = vc[e];
557  size_t i=m_U.num_rows()-1;
558  matrix_row_iterator it = m_U.begin_row(i);
559  UG_ASSERT(it != m_U.end_row(i), i);
560  UG_ASSERT(it.index() == i, i);
561  block_type &uii = it.value();
562  vector_value s = c[i];
563  // check if diag part is significantly smaller than rhs
564  // This may happen when matrix is indefinite with one eigenvalue
565  // zero. In that case, the factorization on the last row is
566  // nearly zero due to round-off errors. In order to allow ill-
567  // scaled matrices (i.e. small matrix entries row-wise) this
568  // is compared to the rhs, that is small in this case as well.
569  if (false && BlockNorm(uii) <= m_small * m_eps * BlockNorm(s)){
570  UG_LOG("ILUT("<<m_eps<<") Warning: Near-zero diagonal entry "
571  "with norm "<<BlockNorm(uii)<<" in last row of U "
572  " with corresponding non-near-zero rhs with norm "
573  << BlockNorm(s) << ". Setting rhs to zero.\n");
574  // set correction to zero
575  c[i] = 0;
576  } else {
577  // c[i] = s/uii;
578  InverseMatMult(c[i], 1.0, uii, s);
579  }
580  }
581  }
582 
583  // handle all other rows
584  if(m_U.num_rows() > 1){
585  for(size_t i=m_U.num_rows()-2; ; i--)
586  {
587  for(size_t e=0; e<vc.size(); e++)
588  {
589  vector_type &c = vc[e];
590  matrix_row_iterator it = m_U.begin_row(i);
591  UG_ASSERT(it != m_U.end_row(i), i);
592  UG_ASSERT(it.index() == i, i);
593  block_type &uii = it.value();
594 
595  vector_value s = c[i];
596  ++it; // skip diag
597  for(; it != m_U.end_row(i); ++it){
598  // s -= it.value() * c[it.index()];
599  MatMultAdd(s, 1.0, s, -1.0, it.value(), c[it.index()] );
600  }
601  // c[i] = s/uii;
602  InverseMatMult(c[i], 1.0, uii, s);
603 
604  if(i==0) break;
605  }
606  }
607  }
608  return true;
609  }
610 
611  // Postprocess routine
612  virtual bool postprocess() {return true;}
613 
614  protected:
618  double m_eps;
619  bool m_info;
621  static const number m_small;
622  std::vector<size_t> newIndex, oldIndex;
623 
627 
629 
630  const vector_type* m_u;
631 };
632 
633 // define constant
634 template <typename TAlgebra>
636 
637 } // end namespace ug
638 
639 #endif
parameterString s
Definition: smart_pointer.h:108
bool invalid() const
returns true if the pointer is invalid, false if not.
Definition: smart_pointer.h:212
void write_debug(const matrix_type &mat, const char *filename)
write debug output for a matrix (if debug writer set)
Definition: debug_writer.h:399
TAlgebra::matrix_type matrix_type
type of matrix
Definition: debug_writer.h:363
Definition: ilut.h:25
ILUTPreconditioner(double eps=1e-6)
Constructor.
Definition: ilut.h:60
TAlgebra algebra_type
Definition: ilut.h:28
matrix_type::connection matrix_connection
Definition: ilut.h:39
bool m_info
Definition: ilut.h:619
TAlgebra::matrix_type matrix_type
Definition: ilut.h:35
double m_eps
Definition: ilut.h:618
void set_sort(bool b)
set cuthill-mckee sort on/off
Definition: ilut.h:122
bool m_bSortIsIdentity
Definition: ilut.h:628
void set_info(bool info)
sets storage information output to true or false
Definition: ilut.h:97
virtual bool preprocess_mat2(matrix_type &mat)
Definition: ilut.h:237
virtual ~ILUTPreconditioner()
Destructor.
Definition: ilut.h:84
matrix_type m_U
Definition: ilut.h:617
IOrderingAlgorithm< TAlgebra, ordering_container_type > ordering_algo_type
Definition: ilut.h:43
virtual bool init(SmartPtr< ILinearOperator< vector_type > > J, const vector_type &u)
implements the ILinearIterator-interface for matrix based preconditioner
Definition: ilut.h:140
std::vector< size_t > ordering_container_type
Ordering type.
Definition: ilut.h:42
matrix_type::const_row_iterator const_matrix_row_iterator
Definition: ilut.h:38
std::vector< size_t > newIndex
Definition: ilut.h:622
bool init(SmartPtr< ILinearOperator< vector_type > > L)
Definition: ilut.h:159
IPreconditioner< TAlgebra > base_type
Definition: ilut.h:56
std::vector< size_t > oldIndex
Definition: ilut.h:622
const vector_type * m_u
Definition: ilut.h:630
virtual SmartPtr< ILinearIterator< vector_type > > clone()
Clone.
Definition: ilut.h:77
void set_show_progress(bool s)
set whether the progress meter should be shown
Definition: ilut.h:103
IPreconditioner< TAlgebra >::matrix_operator_type matrix_operator_type
Matrix Operator type.
Definition: ilut.h:46
bool init(SmartPtr< MatrixOperator< matrix_type, vector_type > > Op)
Definition: ilut.h:177
virtual bool preprocess_mat(matrix_type &mat)
Definition: ilut.h:191
virtual bool supports_parallel() const
returns if parallel solving is supported
Definition: ilut.h:88
ILUTPreconditioner(const ILUTPreconditioner< TAlgebra > &parent)
clone constructor
Definition: ilut.h:68
matrix_type::row_iterator matrix_row_iterator
Definition: ilut.h:37
virtual bool multi_apply(std::vector< vector_type > &vc, const std::vector< vector_type > &vd)
Definition: ilut.h:528
virtual std::string config_string() const
Definition: ilut.h:108
SmartPtr< ordering_algo_type > m_spOrderingAlgo
for ordering algorithms
Definition: ilut.h:625
virtual bool step(SmartPtr< MatrixOperator< matrix_type, vector_type > > pOp, vector_type &c, const vector_type &d)
computes a new correction c = B*d
Definition: ilut.h:424
void set_ordering_algorithm(SmartPtr< ordering_algo_type > ordering_algo)
sets an ordering algorithm
Definition: ilut.h:117
virtual const char * name() const
returns the name of iterator
Definition: ilut.h:137
virtual bool postprocess()
cleans the operator
Definition: ilut.h:612
ordering_container_type m_old_ordering
Definition: ilut.h:626
vector_type::value_type vector_value
Definition: ilut.h:32
void set_threshold(number thresh)
sets threshold for incomplete LU factorisation (added 01122010ih)
Definition: ilut.h:91
matrix_type m_L
Definition: ilut.h:616
matrix_type::value_type block_type
Definition: ilut.h:50
virtual bool applyLU(vector_type &c, const vector_type &d)
Definition: ilut.h:459
TAlgebra::vector_type vector_type
Definition: ilut.h:31
vector_type c2
Definition: ilut.h:615
ordering_container_type m_ordering
Definition: ilut.h:626
bool m_show_progress
Definition: ilut.h:620
virtual bool solve(vector_type &c, const vector_type &d)
Definition: ilut.h:440
static const number m_small
Definition: ilut.h:621
virtual bool preprocess(SmartPtr< MatrixOperator< matrix_type, vector_type > > pOp)
initializes the preconditioner
Definition: ilut.h:185
describes a linear mapping X->Y
Definition: linear_operator.h:80
Definition: IOrderingAlgorithm.h:52
describes a linear iterator that is based on a matrix operator
Definition: preconditioner.h:103
virtual bool init(SmartPtr< ILinearOperator< vector_type > > J, const vector_type &u)
implements the ILinearIterator-interface for matrix based preconditioner
Definition: preconditioner.h:192
Definition: matrix_operator.h:49
Definition: native_cuthill_mckee.h:96
Definition: progress.h:50
void MatAddSlaveRowsToMasterRowOverlap0(TMatrix &mat)
Generates a set of unique global algebra ids.
Definition: parallelization_util.h:106
@ PST_CONSISTENT
Definition: parallel_storage_type.h:68
@ PST_UNIQUE
Definition: parallel_storage_type.h:70
@ PST_ADDITIVE
Definition: parallel_storage_type.h:69
void SetDirichletRow(TSparseMatrix &A, size_t i, size_t alpha)
Definition: sparsematrix_util.h:796
void CollectUniqueElements(std::vector< typename TLayout::Element > &elemsOut, const TLayout &layout)
writes all elements in the interfaces into the resulting vector. avoids doubles.
Definition: pcl_layout_util.h:142
static std::ios_base & reset_floats(std::ios_base &o)
used to unset flags set by std::scientific or std::fixed.
Definition: ostream_util.h:52
const NullSmartPtr SPNULL
The equivalent to NULL for smart pointers.
Definition: smart_pointer.h:90
#define UG_LOG_ALL_PROCS(msg)
Definition: log.h:371
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
#define UG_THROW(msg)
Definition: error.h:57
#define STATIC_ASSERT(expr, msg)
Definition: common.h:61
#define UG_LOG(msg)
Definition: log.h:367
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition: error.h:61
double number
Definition: types.h:124
the ug namespace
static void SetVectorAsPermutation(TVector &Pv, const TVector &v, const std::vector< size_t > &perm)
Definition: permutation_util.h:74
bool MatMultAdd(vector_t &dest, const number &alpha1, const vector_t &v1, const number &beta1, const matrix_t &A1, const vector_t &w1)
calculates dest = alpha1*v1 + beta1 * A1 *w1;
Definition: operations_mat.h:68
static void SetMatrixAsPermutation(TMatrix &PA, const TMatrix &A, const std::vector< size_t > &perm)
Definition: permutation_util.h:50
bool GetInversePermutation(const std::vector< size_t > &perm, std::vector< size_t > &invPerm)
Definition: permutation_util.cpp:39
bool BlockMatrixFiniteAndNotTooBig(TBlock &m, double tooBigValue=1e24)
Definition: vector_util.h:56
bool InverseMatMult(number &dest, const double &beta, const TMat &mat, const TVec &vec)
you can implement this function with GetInverse and MatMult
double BlockNorm(const TYPE &v)
Definition: blocks.h:57
#define PROFILE_BEGIN_GROUP(name, groups)
Definition: profiler.h:255
#define PROGRESS_FINISH(progVarName)
Definition: progress.h:118
#define PROGRESS_START_WITH(progVarName, dSize, msg)
Definition: progress.h:114
#define PROGRESS_UPDATE(progVarName, d)
Definition: progress.h:117
SmartPtr< T, FreePolicy > make_sp(T *inst)
returns a SmartPtr for the passed raw pointer
Definition: smart_pointer.h:836
T value_type
Definition: sparsematrix_interface.h:2