OOFEM 3.0
Loading...
Searching...
No Matches
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 - 2025 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
43namespace oofem {
45
46
47InverseIteration :: InverseIteration(Domain *d, EngngModel *m) :
49 nitem(100)
50{
51}
52
53
55InverseIteration :: solve(SparseMtrx &a, SparseMtrx &b, FloatArray &eigv, FloatMatrix &r, double rtol, int nroot)
56{
58 OOFEM_ERROR("matrices size mismatch");
59 }
60
62
63 int nn = a.giveNumberOfColumns();
64 int nc = min(2 * nroot, nroot + 8);
65 nc = min(nc, nn);
66
67 FloatArray w(nc), ww(nc), t;
68 std :: vector< FloatArray > z(nc, nn), zz(nc, nn), x(nc, nn);
69
70 /* initial setting */
71#if 0
72 ww.add(1.0);
73 for ( int j = 0; j < nc; j++ ) {
74 z[j].add(1.0);
75 }
76#else
77 {
78 FloatArray ad(nn), bd(nn);
79 for ( int i = 1; i <= nn; i++ ) {
80 ad.at(i) = fabs(a.at(i, i));
81 bd.at(i) = fabs(b.at(i, i));
82 }
83 IntArray order;
84 order.enumerate(nn);
85 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); });
86 for ( int i = 0; i < nc; i++ ) {
87 x[i].at(order[i]) = 1.0;
88 b.times(x[i], z[i]);
89 ww.at(i + 1) = z[i].dotProduct(x[i]);
90 }
91 }
92#endif
93
94 int it;
95 for ( it = 0; it < nitem; it++ ) {
96 /* copy zz=z */
97 for ( int j = 0; j < nc; j++ ) {
98 zz[j] = z[j];
99 }
100
101 /* solve matrix equation K.X = M.X */
102 for ( int j = 0; j < nc; j++ ) {
103 solver->solve(a, z[j], x[j]);
104 }
105
106 /* evaluation of Rayleigh quotients */
107 for ( int j = 0; j < nc; j++ ) {
108 w.at(j + 1) = zz[j].dotProduct(x[j]);
109 }
110
111 for ( int j = 0; j < nc; j++ ) {
112 b.times(x[j], z[j]);
113 }
114
115 for ( int j = 0; j < nc; j++ ) {
116 w.at(j + 1) /= z[j].dotProduct(x[j]);
117 }
118
119 /* check convergence */
120 int ac = 0;
121 for ( int j = 1; j <= nc; j++ ) {
122 if ( fabs( ww.at(j) - w.at(j) ) <= fabs( w.at(j) * rtol ) ) {
123 ac++;
124 }
125
126 ww.at(j) = w.at(j);
127 }
128
129 //printf ("\n iteration %d %d",it,ac);
130 //w.printYourself();
131
132 /* Gramm-Schmidt ortogonalization */
133 for ( int j = 0; j < nc; j++ ) {
134 if ( j != 0 ) {
135 b.times(x[j], t);
136 }
137
138 for ( int ii = 0; ii < j; ii++ ) {
139 x[j].add( -x[ii].dotProduct(t), x[ii] );
140 }
141
142 b.times(x[j], t);
143 x[j].times( 1.0 / sqrt( x[j].dotProduct(t) ) );
144 }
145
146 if ( ac > nroot ) {
147 break;
148 }
149
150 /* compute new approximation of Z */
151 for ( int j = 0; j < nc; j++ ) {
152 b.times(x[j], z[j]);
153 }
154 }
155
156 // copy results
157 IntArray order;
158 order.enumerate(w.giveSize());
159 std :: sort(order.begin(), order.end(), [&w](int a, int b) { return w.at(a) < w.at(b); });
160
161 eigv.resize(nroot);
162 r.resize(nn, nroot);
163 for ( int i = 1; i <= nroot; i++ ) {
164 eigv.at(i) = w.at(order.at(i));
165 r.setColumn(x[order.at(i) - 1], i);
166 }
167
168 if ( it < nitem ) {
169 OOFEM_LOG_INFO("InverseIt info: convergence reached in %d iterations\n", it);
170 } else {
171 OOFEM_WARNING("convergence not reached after %d iterations\n", it);
172 return CR_DIVERGED_ITS;
173 }
174
175 return CR_CONVERGED;
176}
177} // end namespace oofem
#define REGISTER_GeneralizedEigenValueSolver(class, type)
std::unique_ptr< SparseLinearSystemNM > createSparseLinSolver(LinSystSolverType st, Domain *d, EngngModel *m)
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
void setColumn(const FloatArray &src, int c)
std::vector< int >::iterator end()
Definition intarray.h:72
void enumerate(int maxVal)
Definition intarray.C:85
std::vector< int >::iterator begin()
Definition intarray.h:71
int & at(std::size_t i)
Definition intarray.h:104
int nitem
Max number of iterations.
Definition inverseit.h:86
Domain * domain
Pointer to domain.
Definition nummet.h:84
EngngModel * engngModel
Pointer to engineering model.
Definition nummet.h:86
SparseGeneralEigenValueSystemNM(Domain *d, EngngModel *m)
Constructor.
virtual double & at(int i, int j)=0
Returns coefficient at position (i,j).
int giveNumberOfColumns() const
Returns number of columns of receiver.
Definition sparsemtrx.h:116
virtual void times(const FloatArray &x, FloatArray &answer) const
Definition sparsemtrx.h:137
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
ClassFactory & GiveClassFactory()
@ CR_DIVERGED_ITS

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