OOFEM 3.0
Loading...
Searching...
No Matches
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
37namespace oofem {
38CompCol_ICPreconditioner :: CompCol_ICPreconditioner(const SparseMtrx &A, InputRecord &attributes) :
39 Preconditioner(A, attributes)
40{ }
41
42
43void
44CompCol_ICPreconditioner :: initializeFrom(InputRecord &ir)
45{
46 Preconditioner :: initializeFrom(ir);
47}
48
49
50void
51CompCol_ICPreconditioner :: init(const SparseMtrx &A)
52{
53 if ( dynamic_cast< const SymCompCol * >(&A) ) {
54 this->initialize( static_cast< const SymCompCol & >(A) );
55 } else if ( dynamic_cast< const CompCol * >(&A) ) {
56 this->initialize( static_cast< const CompCol & >(A) );
57 } else {
58 OOFEM_ERROR("unsupported sparse matrix type");
59 }
60}
61
62
63void
64CompCol_ICPreconditioner :: initialize(const CompCol &A)
65{
66 dim [ 0 ] = A.giveNumberOfRows();
67 dim [ 1 ] = A.giveNumberOfColumns();
68
69 pntr.resize(dim [ 1 ] + 1);
70
71 nz = 0;
72 for ( int k = 0; k < dim [ 1 ]; k++ ) {
73 for ( int j = A.col_ptr(k); j < A.col_ptr(k + 1); j++ ) {
74 if ( A.row_ind(j) >= k ) {
75 nz++;
76 }
77 }
78 }
79
80 val.resize(nz);
81 indx.resize(nz);
82
83 // Copy just triangular part
84 pntr[0] = 0;
85 for ( int k = 0; k < dim [ 1 ]; k++ ) {
86 pntr[k + 1] = pntr[k];
87 for ( int j = A.col_ptr(k); j < A.col_ptr(k + 1); j++ ) {
88 if ( A.row_ind(j) >= k ) {
89 int i = pntr[k + 1]++;
90 val[i] = A.values(j);
91 indx[i] = A.row_ind(j);
92 }
93 }
94 }
95
96 for ( int i = 0; i < dim [ 1 ]; i++ ) {
97 if ( indx[ pntr[i] ] != i ) {
98 OOFEM_ERROR("diagonal not found!");
99 }
100 }
101
102 this->ICFactor();
103}
104
105
106void
107CompCol_ICPreconditioner :: solve(const FloatArray &x, FloatArray &y) const
108{
109 y = x;
110 this->ICSolve(y);
111}
112
113
114void
115CompCol_ICPreconditioner :: trans_solve(const FloatArray &x, FloatArray &y) const
116{
117 y = x;
118 this->ICSolve(y);
119}
120
121
122void
123CompCol_ICPreconditioner :: ICFactor()
124{
125 int n = pntr.giveSize() - 1;
126
127 for ( int k = 0; k < n - 1; k++ ) {
128 int d = pntr[k];
129 double z = val[d] = sqrt( val[d] );
130
131 for ( int i = d + 1; i < pntr[k + 1]; i++ ) {
132 val[i] /= z;
133 }
134
135 for ( int i = d + 1; i < pntr[k + 1]; i++ ) {
136 double z = val[i];
137 int h = indx[i];
138 int g = i;
139
140 for ( int j = pntr[h]; j < pntr[h + 1]; j++ ) {
141 for ( ; g < pntr[k + 1] && indx[g + 1] <= indx[j]; g++ ) {
142 if ( indx[g] == indx[j] ) {
143 val[j] -= z * val[g];
144 }
145 }
146 }
147 }
148 }
149
150 int d = pntr[n - 1];
151 val[d] = sqrt( val[d] );
152}
153
154
155void
156CompCol_ICPreconditioner :: ICSolve(FloatArray &dest) const
157{
158 int M = dest.giveSize();
159 FloatArray work(M);
160 // lower diag
161
162 // solve Uw=x
163 for ( int i = 0; i < M; i++ ) {
164 double temp;
165 work[i] = temp = ( dest[i] + work[i] ) / val[ pntr[i] ];
166 for ( int t = pntr[i] + 1; t < pntr[i + 1]; t++ ) {
167 work[ indx[t] ] -= val[t] * temp;
168 }
169 }
170
171 dest.zero();
172 // solve U^Ty=w
173 for ( int i = M - 1; i >= 0; i-- ) {
174 for ( int t = pntr[i] + 1; t < pntr[i + 1]; t++ ) {
175 dest[i] -= val[t] * dest( indx[t] );
176 }
177
178 dest[i] = ( work[i] + dest[i] ) / val[ pntr[i] ];
179 }
180}
181
182
183void
184CompCol_ICPreconditioner :: qsortRow(IntArray &src, FloatArray &val, int l, int r)
185{
186 if ( r <= l ) {
187 return;
188 }
189
190 int i = qsortRowPartition(src, val, l, r);
191 qsortRow(src, val, l, i - 1);
192 qsortRow(src, val, i + 1, r);
193}
194
195
196int
197CompCol_ICPreconditioner :: qsortRowPartition(IntArray &src, FloatArray &val, int l, int r)
198{
199 int i = l - 1, j = r;
200 int v = src[r];
201
202 for ( ; ; ) {
203 while ( ( src[++i] < v ) ) {
204 ;
205 }
206
207 while ( ( v < src[--j] ) ) {
208 if ( j == l ) {
209 break;
210 }
211 }
212
213 if ( i >= j ) {
214 break;
215 }
216
217 std::swap(src[i], src[j]);
218 std::swap(val[i], val[j]);
219 }
220
221 std::swap(src[i], src[r]);
222 std::swap(val[i], val[r]);
223
224 return i;
225}
226} // end namespace oofem
void qsortRow(IntArray &, FloatArray &, int l, int r)
Definition icprecond.C:184
int qsortRowPartition(IntArray &, FloatArray &, int l, int r)
Definition icprecond.C:197
void ICSolve(FloatArray &dest) const
Definition icprecond.C:156
void initialize(const CompCol &A)
Definition icprecond.C:64
const int & row_ind(int i) const
Definition compcol.h:134
const int & col_ptr(int i) const
Definition compcol.h:135
const double & values(int i) const
Definition compcol.h:133
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
Preconditioner(const SparseMtrx &a, InputRecord &attributes)
Definition precond.C:38
int giveNumberOfRows() const
Returns number of rows of receiver.
Definition sparsemtrx.h:114
int giveNumberOfColumns() const
Returns number of columns of receiver.
Definition sparsemtrx.h:116
#define OOFEM_ERROR(...)
Definition error.h:79

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011