OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
inverseit.C
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33  */
34 
35 #include "inverseit.h"
36 #include "floatmatrix.h"
37 #include "floatarray.h"
38 #include "sparsemtrx.h"
39 #include "mathfem.h"
40 #include "sparselinsystemnm.h"
41 #include "classfactory.h"
42 
43 namespace oofem {
45 
46 
49 {
50  nitem = 100; // max number of iterations
51 }
52 
53 
55 
57 InverseIteration :: solve(SparseMtrx &a, SparseMtrx &b, FloatArray &_eigv, FloatMatrix &_r, double rtol, int nroot)
58 {
59  if ( a.giveNumberOfColumns() != b.giveNumberOfColumns() ) {
60  OOFEM_ERROR("matrices size mismatch");
61  }
62 
64 
65  int nn = a.giveNumberOfColumns();
66  int nc = min(2 * nroot, nroot + 8);
67  nc = min(nc, nn);
68 
69  FloatArray w(nc), ww(nc), t;
70  std :: vector< FloatArray > z(nc, nn), zz(nc, nn), x(nc, nn);
71 
72  /* initial setting */
73 #if 0
74  ww.add(1.0);
75  for ( int j = 0; j < nc; j++ ) {
76  z[j].add(1.0);
77  }
78 #else
79  {
80  FloatArray ad(nn), bd(nn);
81  for ( int i = 1; i <= nn; i++ ) {
82  ad.at(i) = fabs(a.at(i, i));
83  bd.at(i) = fabs(b.at(i, i));
84  }
85  IntArray order;
86  order.enumerate(nn);
87  std :: sort(order.begin(), order.end(), [&ad, &bd](int a, int b) { return bd.at(a) * ad.at(b) > bd.at(b) * ad.at(a); });
88  for ( int i = 0; i < nc; i++ ) {
89  x[i].at(order[i]) = 1.0;
90  b.times(x[i], z[i]);
91  ww.at(i + 1) = z[i].dotProduct(x[i]);
92  }
93  }
94 #endif
95 
96  int it;
97  for ( it = 0; it < nitem; it++ ) {
98  /* copy zz=z */
99  for ( int j = 0; j < nc; j++ ) {
100  zz[j] = z[j];
101  }
102 
103  /* solve matrix equation K.X = M.X */
104  for ( int j = 0; j < nc; j++ ) {
105  solver->solve(a, z[j], x[j]);
106  }
107 
108  /* evaluation of Rayleigh quotients */
109  for ( int j = 0; j < nc; j++ ) {
110  w.at(j + 1) = zz[j].dotProduct(x[j]);
111  }
112 
113  for ( int j = 0; j < nc; j++ ) {
114  b.times(x[j], z[j]);
115  }
116 
117  for ( int j = 0; j < nc; j++ ) {
118  w.at(j + 1) /= z[j].dotProduct(x[j]);
119  }
120 
121  /* check convergence */
122  int ac = 0;
123  for ( int j = 1; j <= nc; j++ ) {
124  if ( fabs( ww.at(j) - w.at(j) ) <= fabs( w.at(j) * rtol ) ) {
125  ac++;
126  }
127 
128  ww.at(j) = w.at(j);
129  }
130 
131  //printf ("\n iteration %d %d",it,ac);
132  //w.printYourself();
133 
134  /* Gramm-Schmidt ortogonalization */
135  for ( int j = 0; j < nc; j++ ) {
136  if ( j != 0 ) {
137  b.times(x[j], t);
138  }
139 
140  for ( int ii = 0; ii < j; ii++ ) {
141  x[j].add( -x[ii].dotProduct(t), x[ii] );
142  }
143 
144  b.times(x[j], t);
145  x[j].times( 1.0 / sqrt( x[j].dotProduct(t) ) );
146  }
147 
148  if ( ac > nroot ) {
149  break;
150  }
151 
152  /* compute new approximation of Z */
153  for ( int j = 0; j < nc; j++ ) {
154  b.times(x[j], z[j]);
155  }
156  }
157 
158  // copy results
159  IntArray order;
160  order.enumerate(w.giveSize());
161  std :: sort(order.begin(), order.end(), [&w](int a, int b) { return w.at(a) < w.at(b); });
162 
163  _eigv.resize(nroot);
164  _r.resize(nn, nroot);
165  for ( int i = 1; i <= nroot; i++ ) {
166  _eigv.at(i) = w.at(order.at(i));
167  _r.setColumn(x[order.at(i) - 1], i);
168  }
169 
170  if ( it < nitem ) {
171  OOFEM_LOG_INFO("InverseIt info: convergence reached in %d iterations\n", it);
172  } else {
173  OOFEM_WARNING("convergence not reached after %d iterations\n", it);
174  }
175 
176  return NM_Success;
177 }
178 } // end namespace oofem
void enumerate(int maxVal)
Resizes receiver and enumerates from 1 to the maximum value given.
Definition: intarray.C:136
virtual NM_Status solve(SparseMtrx &A, FloatArray &b, FloatArray &x)=0
Solves the given sparse linear system of equations .
#define NM_Success
Numerical method exited with success.
Definition: nmstatus.h:47
Class and object Domain.
Definition: domain.h:115
InverseIteration(Domain *d, EngngModel *m)
Definition: inverseit.C:47
Base class for all matrices stored in sparse format.
Definition: sparsemtrx.h:60
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
This base class is an abstraction for all numerical methods solving sparse linear system of equations...
std::vector< int >::iterator end()
Definition: intarray.h:71
virtual double & at(int i, int j)=0
Returns coefficient at position (i,j).
unsigned long NM_Status
Mask defining NumMetod Status; which can be asked after finishing computation by Numerical Method...
Definition: nmstatus.h:44
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
void sort(IntArray &arry, operation op)
Sorts the receiver using quicksort algorithm.
Definition: intarray.h:416
virtual NM_Status solve(SparseMtrx &A, SparseMtrx &B, FloatArray &x, FloatMatrix &v, double rtol, int nroot)
Solves the given sparse generalized eigen value system of equations .
Definition: inverseit.C:57
REGISTER_GeneralizedEigenValueSolver(InverseIteration, GES_InverseIt)
Domain * domain
Pointer to domain.
Definition: nummet.h:84
#define OOFEM_LOG_INFO(...)
Definition: logger.h:127
#define OOFEM_ERROR(...)
Definition: error.h:61
ClassFactory & GiveClassFactory()
This function must be used by all code that run at link time to ensure that the classFactory is const...
Definition: classfactory.C:53
Class representing vector of real numbers.
Definition: floatarray.h:82
SparseLinearSystemNM * createSparseLinSolver(LinSystSolverType st, Domain *d, EngngModel *m)
Creates new instance of SparseLinearSystemNM corresponding to given type.
Definition: classfactory.C:120
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
void setColumn(const FloatArray &src, int c)
Sets the values of the matrix in specified column.
Definition: floatmatrix.C:648
int giveNumberOfColumns() const
Returns number of columns of receiver.
Definition: sparsemtrx.h:116
std::vector< int >::iterator begin()
Definition: intarray.h:70
int min(int i, int j)
Returns smaller value from two given decimals.
Definition: mathfem.h:59
virtual ~InverseIteration()
Definition: inverseit.C:54
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
virtual void times(const FloatArray &x, FloatArray &answer) const
Evaluates .
Definition: sparsemtrx.h:137
the oofem namespace is to define a context or scope in which all oofem names are defined.
This base class is an abstraction for all numerical methods solving sparse linear system of equations...
EngngModel * engngModel
Pointer to engineering model.
Definition: nummet.h:86
#define OOFEM_WARNING(...)
Definition: error.h:62
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