FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
chebyshev.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, FEAT
10#include <kernel/solver/iterative.hpp>
11
12namespace FEAT
13{
14 namespace Solver
15 {
24 template<typename Matrix_, typename Filter_>
25 class Chebyshev :
26 public IterativeSolver<typename Matrix_::VectorTypeR>
27 {
28 public:
30 typedef Matrix_ MatrixType;
32 typedef Filter_ FilterType;
34 typedef typename MatrixType::VectorTypeL VectorType;
36 typedef typename MatrixType::DataType DataType;
39
40 protected:
57
58 public:
69 explicit Chebyshev(const MatrixType& matrix, const FilterType& filter,
70 const DataType fraction_min_ev = DataType(0.5), const DataType fraction_max_ev = DataType(0.8)) :
71 BaseClass("Chebyshev"),
72 _system_matrix(matrix),
73 _system_filter(filter),
74 _min_ev(0),
75 _max_ev(0),
76 _fraction_min_ev(fraction_min_ev),
77 _fraction_max_ev(fraction_max_ev)
78 {
79 // set communicator by system matrix
80 this->_set_comm_by_matrix(matrix);
81 }
82
101 explicit Chebyshev(const String& section_name, const PropertyMap* section,
102 const MatrixType& matrix, const FilterType& filter) :
103 BaseClass("Chebyshev", section_name, section),
104 _system_matrix(matrix),
105 _system_filter(filter),
106 _min_ev(DataType(0)),
107 _max_ev(DataType(0)),
110 {
111 // set communicator by system matrix
112 this->_set_comm_by_matrix(matrix);
113 auto fmin_p = section->query("fraction_min_ev");
114 if(fmin_p.second && !fmin_p.first.parse(this->_fraction_min_ev))
115 throw ParseError(section_name + ".fraction_min_ev", fmin_p.first, "a float");
116
117 auto fmax_p = section->query("fraction_max_ev");
118 if(fmax_p.second && !fmax_p.first.parse(this->_fraction_max_ev))
119 throw ParseError(section_name + ".fraction_max_ev", fmax_p.first, "a float");
120 }
121
125 virtual ~Chebyshev()
126 {
127 }
128
130 virtual String name() const override
131 {
132 return "Chebyshev";
133 }
134
142 void set_fraction_min_ev(DataType fraction_min_ev)
143 {
144 _fraction_min_ev = fraction_min_ev;
145 }
146
154 void set_fraction_max_ev(DataType fraction_max_ev)
155 {
156 _fraction_max_ev = fraction_max_ev;
157 }
158
160 virtual void init_symbolic() override
161 {
163 _vec_def = this->_system_matrix.create_vector_r();
164 _vec_cor = this->_system_matrix.create_vector_r();
165 }
166
168 virtual void done_symbolic() override
169 {
170 this->_vec_cor.clear();
171 this->_vec_def.clear();
173 }
174
176 virtual void init_numeric() override
177 {
179
180 //PowerMethod for maximum eigenvalue
181 //http://blogs.sas.com/content/iml/2012/05/09/the-power-method.html
182 //https://en.wikipedia.org/wiki/Power_iteration
183 VectorType& v(this->_vec_cor);
184 VectorType& z(this->_vec_def);
185 const MatrixType& matrix(this->_system_matrix);
186 v.format(DataType(3));
187 DataType tolerance(DataType(1e-4));
188 Index max_iters(40);
189 v.scale(v, DataType(1) / v.norm2());
190 DataType lambda_old(0), lambda(0);
191 for (Index i(0) ; i < max_iters ; ++i)
192 {
193 matrix.apply(z, v);
194 v.scale(z, DataType(1) / z.norm2());
195 lambda = v.dot(z);
196 if (Math::abs((lambda - lambda_old) / lambda) < tolerance)
197 break;
198 lambda_old = lambda;
199 }
200
201 _min_ev = lambda * _fraction_min_ev;
202 _max_ev = lambda * _fraction_max_ev;
203 }
204
205 virtual Status apply(VectorType& vec_cor, const VectorType& vec_def) override
206 {
207 // save defect
208 this->_vec_def.copy(vec_def);
209
210 // clear solution vector
211 vec_cor.format();
212
213 // apply
214 this->_status = _apply_intern(vec_cor, vec_def);
215 this->plot_summary();
216 return this->_status;
217 }
218
219 virtual Status correct(VectorType& vec_sol, const VectorType& vec_rhs) override
220 {
221 // compute defect
222 this->_system_matrix.apply(this->_vec_def, vec_sol, vec_rhs, -DataType(1));
223 this->_system_filter.filter_def(this->_vec_def);
224
225 // apply
226 this->_status = _apply_intern(vec_sol, vec_rhs);
227 this->plot_summary();
228 return this->_status;
229 }
230
231 protected:
232 virtual Status _apply_intern(VectorType& vec_sol, const VectorType& vec_rhs)
233 {
234 Statistics::add_solver_expression(std::make_shared<ExpressionStartSolve>(this->name()));
235
236 VectorType& vec_def(this->_vec_def);
237 VectorType& vec_cor(this->_vec_cor);
238 const MatrixType& matrix(this->_system_matrix);
239 const FilterType& filter(this->_system_filter);
240
241 // compute initial defect
242 Status status = this->_set_initial_defect(vec_def, vec_sol);
243
244 DataType d = (_max_ev + _min_ev) / DataType(2);
245 DataType c = (_max_ev - _min_ev) / DataType(2);
246 DataType alpha(0);
247 DataType beta(0);
248 vec_cor.scale(vec_def, (DataType(1) / d));
249
250 // start iterating
251 while(status == Status::progress)
252 {
253 switch (this->get_num_iter())
254 {
255 case 0:
256 alpha = DataType(1) / d;
257 break;
258 case 1:
259 alpha = DataType(2) * d * (DataType(1) / ((DataType(2) * d * d) - (c * c)));
260 break;
261 default:
262 alpha = DataType(1) / (d - ((alpha * c * c) / DataType(4)));
263 }
264
265 beta = (alpha * d) - DataType(1);
266 vec_cor.scale(vec_cor, beta);
267 vec_cor.axpy(vec_def, alpha);
268
269 // update solution vector
270 vec_sol.axpy(vec_cor);
271
272 // compute new defect vector
273 matrix.apply(vec_def, vec_sol, vec_rhs, -DataType(1));
274 filter.filter_def(vec_def);
275
276 // compute new defect norm
277 status = this->_set_new_defect(vec_def, vec_sol);
278 }
279
280 // return our status
281 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), status, this->get_num_iter()));
282 return status;
283 }
284 }; // class Chebyshev<...>
285
298 template<typename Matrix_, typename Filter_>
299 inline std::shared_ptr<Chebyshev<Matrix_, Filter_>> new_chebyshev(
300 const Matrix_& matrix, const Filter_& filter,
301 const typename Matrix_::DataType fraction_min_ev = typename Matrix_::DataType(0.03),
302 const typename Matrix_::DataType fraction_max_ev = typename Matrix_::DataType(1.1))
303 {
304 return std::make_shared<Chebyshev<Matrix_, Filter_>>(matrix, filter, fraction_min_ev, fraction_max_ev);
305 }
306
325 template<typename Matrix_, typename Filter_>
326 inline std::shared_ptr<Chebyshev<Matrix_, Filter_>> new_chebyshev(
327 const String& section_name, const PropertyMap* section,
328 const Matrix_& matrix, const Filter_& filter)
329 {
330 return std::make_shared<Chebyshev<Matrix_, Filter_>>(section_name, section, matrix, filter);
331 }
332 } // namespace Solver
333} // namespace FEAT
FEAT Kernel base header.
Class for parser related errors.
Definition: exception.hpp:132
A class organizing a tree of key-value pairs.
std::pair< String, bool > query(String key_path) const
Queries a value by its key path.
Chebyshev Polynomial implementation.
Definition: chebyshev.hpp:27
void set_fraction_min_ev(DataType fraction_min_ev)
Sets the minimum eigenvalue fraction.
Definition: chebyshev.hpp:142
virtual void done_symbolic() override
Symbolic finalization method.
Definition: chebyshev.hpp:168
Chebyshev(const String &section_name, const PropertyMap *section, const MatrixType &matrix, const FilterType &filter)
Constructor using a PropertyMap.
Definition: chebyshev.hpp:101
IterativeSolver< VectorType > BaseClass
Our base class.
Definition: chebyshev.hpp:38
MatrixType::DataType DataType
The floating point precision.
Definition: chebyshev.hpp:36
DataType _fraction_max_ev
maximum eigenvalue fraction
Definition: chebyshev.hpp:56
virtual void init_symbolic() override
Symbolic initialization method.
Definition: chebyshev.hpp:160
Matrix_ MatrixType
The matrix type.
Definition: chebyshev.hpp:30
Filter_ FilterType
The filter type.
Definition: chebyshev.hpp:32
DataType _min_ev
the minium eigenvalue of the matrix
Definition: chebyshev.hpp:50
DataType _max_ev
the maximum eigenvalue of the matrix
Definition: chebyshev.hpp:52
const MatrixType & _system_matrix
the matrix for the solver
Definition: chebyshev.hpp:42
DataType _fraction_min_ev
minimum eigenvalue fraction
Definition: chebyshev.hpp:54
const FilterType & _system_filter
the filter for the solver
Definition: chebyshev.hpp:44
VectorType _vec_cor
correction vector
Definition: chebyshev.hpp:48
virtual String name() const override
Returns a descriptive string.
Definition: chebyshev.hpp:130
Chebyshev(const MatrixType &matrix, const FilterType &filter, const DataType fraction_min_ev=DataType(0.5), const DataType fraction_max_ev=DataType(0.8))
Constructor.
Definition: chebyshev.hpp:69
void set_fraction_max_ev(DataType fraction_max_ev)
Sets the maximum eigenvalue fraction.
Definition: chebyshev.hpp:154
virtual ~Chebyshev()
Empty virtual destructor.
Definition: chebyshev.hpp:125
MatrixType::VectorTypeL VectorType
The type of vector this solver can be applied to.
Definition: chebyshev.hpp:34
VectorType _vec_def
defect vector
Definition: chebyshev.hpp:46
virtual void init_numeric() override
Numeric initialization method.
Definition: chebyshev.hpp:176
Abstract base-class for iterative solvers.
Definition: iterative.hpp:198
Index get_num_iter() const
Returns number of performed iterations.
Definition: iterative.hpp:462
Status _status
current status of the solver
Definition: iterative.hpp:213
void _set_comm_by_matrix(const Matrix_ &matrix)
Sets the communicator for the solver from a matrix.
Definition: iterative.hpp:680
virtual Status _set_new_defect(const VectorType &vec_def, const VectorType &vec_sol)
Internal function: sets the new (next) defect vector.
Definition: iterative.hpp:924
virtual void plot_summary() const
Plot a summary of the last solver run.
Definition: iterative.hpp:627
virtual Status _set_initial_defect(const VectorType &vec_def, const VectorType &vec_sol)
Internal function: sets the initial defect vector.
Definition: iterative.hpp:802
virtual void init_symbolic()
Symbolic initialization method.
Definition: base.hpp:227
virtual void init_numeric()
Numeric initialization method.
Definition: base.hpp:237
virtual void done_symbolic()
Symbolic finalization method.
Definition: base.hpp:255
String class implementation.
Definition: string.hpp:47
T_ abs(T_ x)
Returns the absolute value.
Definition: math.hpp:275
Status
Solver status return codes enumeration.
Definition: base.hpp:47
@ progress
continue iteration (internal use only)
std::shared_ptr< Chebyshev< Matrix_, Filter_ > > new_chebyshev(const Matrix_ &matrix, const Filter_ &filter, const typename Matrix_::DataType fraction_min_ev=typename Matrix_::DataType(0.03), const typename Matrix_::DataType fraction_max_ev=typename Matrix_::DataType(1.1))
Creates a new Chebyshev solver object.
Definition: chebyshev.hpp:299
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.