OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
icprecond.C
Go to the documentation of this file.
1 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
2 /* ******** *** SparseLib++ */
3 /* ******* ** *** *** *** v. 1.5c */
4 /* ***** *** ******** ******** */
5 /* ***** *** ******** ******** R. Pozo */
6 /* ** ******* *** ** *** *** K. Remington */
7 /* ******** ******** A. Lumsdaine */
8 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
9 /* */
10 /* */
11 /* SparseLib++ : Sparse Matrix Library */
12 /* */
13 /* National Institute of Standards and Technology */
14 /* University of Notre Dame */
15 /* Authors: R. Pozo, K. Remington, A. Lumsdaine */
16 /* */
17 /* NOTICE */
18 /* */
19 /* Permission to use, copy, modify, and distribute this software and */
20 /* its documentation for any purpose and without fee is hereby granted */
21 /* provided that the above notice appear in all copies and supporting */
22 /* documentation. */
23 /* */
24 /* Neither the Institutions (National Institute of Standards and Technology, */
25 /* University of Notre Dame) nor the Authors make any representations about */
26 /* the suitability of this software for any purpose. This software is */
27 /* provided ``as is'' without expressed or implied warranty. */
28 /* */
29 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
30 
31 // adapted & optimized by Borek Patzak
32 
33 #include "icprecond.h"
34 #include "symcompcol.h"
35 #include "mathfem.h"
36 
37 namespace oofem {
39  Preconditioner(A, attributes)
40 { }
41 
44 {
46 }
47 
48 void
50 {
51  if ( dynamic_cast< const SymCompCol * >(&A) ) {
52  this->initialize( * ( ( SymCompCol * ) & A ) );
53  } else if ( dynamic_cast< const CompCol * >(&A) ) {
54  this->initialize( * ( ( CompCol * ) & A ) );
55  } else {
56  OOFEM_ERROR("unsupported sparse matrix type");
57  }
58 }
59 
60 
61 
62 
63 void
65 {
66  dim_ [ 0 ] = A.dim(0);
67  dim_ [ 1 ] = A.dim(1);
68 
69  pntr_.resize(A.dim(1) + 1);
70 
71 
72  int i, j, k;
73 
74  nz_ = 0;
75  for ( k = 0; k < dim_ [ 1 ]; k++ ) {
76  for ( j = A.col_ptr(k); j < A.col_ptr(k + 1); j++ ) {
77  if ( A.row_ind(j) >= k ) {
78  nz_++;
79  }
80  }
81  }
82 
83  val_.resize(nz_);
84  indx_.resize(nz_);
85 
86  // Copy just triangular part
87  pntr_(0) = 0;
88  for ( k = 0; k < dim_ [ 1 ]; k++ ) {
89  pntr_(k + 1) = pntr_(k);
90  for ( j = A.col_ptr(k); j < A.col_ptr(k + 1); j++ ) {
91  if ( A.row_ind(j) >= k ) {
92  i = pntr_(k + 1)++;
93  val_(i) = A.val(j);
94  indx_(i) = A.row_ind(j);
95  }
96  }
97  }
98 
99  // for (i = 0; i < dim_[1]; i++)
100  // qsortRow(indx_, val_, pntr_(i), pntr_(i+1) -1);
101 
102  for ( i = 0; i < dim_ [ 1 ]; i++ ) {
103  if ( indx_( pntr_(i) ) != i ) {
104  OOFEM_ERROR("diagonal not found!");
105  }
106  }
107 
108  this->ICFactor();
109 }
110 
111 
112 void
114 {
115  y = x;
116  this->ICSolve(y);
117 }
118 
119 
120 void
122 {
123  y = x;
124  this->ICSolve(y);
125 }
126 
127 
128 void
130 {
131  int d, g, h, i, j, k, n = pntr_.giveSize() - 1;
132  double z;
133 
134  for ( k = 0; k < n - 1; k++ ) {
135  d = pntr_(k);
136  z = val_(d) = sqrt( val_(d) );
137 
138  for ( i = d + 1; i < pntr_(k + 1); i++ ) {
139  val_(i) /= z;
140  }
141 
142  for ( i = d + 1; i < pntr_(k + 1); i++ ) {
143  z = val_(i);
144  h = indx_(i);
145  g = i;
146 
147  for ( j = pntr_(h); j < pntr_(h + 1); j++ ) {
148  for ( ; g < pntr_(k + 1) && indx_(g + 1) <= indx_(j); g++ ) {
149  if ( indx_(g) == indx_(j) ) {
150  val_(j) -= z * val_(g);
151  }
152  }
153  }
154  }
155  }
156 
157  d = pntr_(n - 1);
158  val_(d) = sqrt( val_(d) );
159 }
160 
161 
162 void
164 {
165  int i, t, M = dest.giveSize();
166  FloatArray work(M);
167  double val;
168  // lower diag
169 
170  work.zero();
171  // solve Uw=x
172  for ( i = 0; i < M; i++ ) {
173  work(i) = val = ( dest(i) + work(i) ) / val_( pntr_(i) );
174  for ( t = pntr_(i) + 1; t < pntr_(i + 1); t++ ) {
175  work( indx_(t) ) -= val_(t) * val;
176  }
177  }
178 
179  dest.zero();
180  // solve U^Ty=w
181  for ( i = M - 1; i >= 0; i-- ) {
182  for ( t = pntr_(i) + 1; t < pntr_(i + 1); t++ ) {
183  dest(i) -= val_(t) * dest( indx_(t) );
184  }
185 
186  dest(i) = ( work(i) + dest(i) ) / val_( pntr_(i) );
187  }
188 }
189 
190 
191 void
193 {
194  if ( r <= l ) {
195  return;
196  }
197 
198  int i = qsortRowPartition(src, val, l, r);
199  qsortRow(src, val, l, i - 1);
200  qsortRow(src, val, i + 1, r);
201 }
202 
203 
204 int
206 {
207  int i = l - 1, j = r;
208  int v = src(r);
209  int swap;
210  double dswap;
211 
212  for ( ; ; ) {
213  while ( ( src(++i) < v ) ) {
214  ;
215  }
216 
217  while ( ( v < src(--j) ) ) {
218  if ( j == l ) {
219  break;
220  }
221  }
222 
223  if ( i >= j ) {
224  break;
225  }
226 
227  swap = src(i);
228  src(i) = src(j);
229  src(j) = swap;
230  dswap = val(i);
231  val(i) = val(j);
232  val(j) = dswap;
233  }
234 
235  swap = src(i);
236  src(i) = src(r);
237  src(r) = swap;
238  dswap = val(i);
239  val(i) = val(r);
240  val(r) = dswap;
241 
242  return i;
243 }
244 } // end namespace oofem
void initialize(const CompCol &A)
Definition: icprecond.C:64
int qsortRowPartition(IntArray &, FloatArray &, int l, int r)
Definition: icprecond.C:205
void solve(const FloatArray &rhs, FloatArray &solution) const
Solves the linear system.
Definition: icprecond.C:113
void qsortRow(IntArray &, FloatArray &, int l, int r)
Definition: icprecond.C:192
Base class for all matrices stored in sparse format.
Definition: sparsemtrx.h:60
const int & row_ind(int i) const
Definition: compcol.h:139
const int & col_ptr(int i) const
Definition: compcol.h:140
Class implementing an array of integers.
Definition: intarray.h:61
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver from given record. Empty implementation.
Definition: icprecond.C:43
#define OOFEM_ERROR(...)
Definition: error.h:61
int dim(int i) const
Definition: compcol.h:141
void ICSolve(FloatArray &dest) const
Definition: icprecond.C:163
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
Implementation of symmetric sparse matrix stored using compressed column/row storage.
Definition: symcompcol.h:81
Class representing vector of real numbers.
Definition: floatarray.h:82
Abstract class for IML++ compatible preconditioner.
Definition: precond.h:53
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
const double & val(int i) const
Definition: compcol.h:138
void trans_solve(const FloatArray &rhs, FloatArray &solution) const
Solves the transposed system.
Definition: icprecond.C:121
Class representing the general Input Record.
Definition: inputrecord.h:101
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
virtual void init(const SparseMtrx &a)
Initializes the receiver (constructs the preconditioning matrix M) of given matrix.
Definition: icprecond.C:49
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
the oofem namespace is to define a context or scope in which all oofem names are defined.
CompCol_ICPreconditioner()
Constructor. The user should call initializeFrom and init services in this given order to ensure cons...
Definition: icprecond.h:57
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver from given record. Empty implementation.
Definition: precond.h:115
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:29 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011