FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
gropppcg.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
9#include <kernel/solver/iterative.hpp>
10
11namespace FEAT
12{
13 namespace Solver
14 {
32 template<
33 typename Matrix_,
34 typename Filter_>
35 class GroppPCG :
36 public PreconditionedIterativeSolver<typename Matrix_::VectorTypeR>
37 {
38 public:
39 typedef Matrix_ MatrixType;
40 typedef Filter_ FilterType;
41 typedef typename MatrixType::VectorTypeR VectorType;
42 typedef typename MatrixType::DataType DataType;
44
46
47 protected:
49 const MatrixType& _system_matrix;
51 const FilterType& _system_filter;
53 VectorType _vec_r, _vec_z, _vec_s, _vec_p, _vec_S, _vec_Z;
54
55 public:
68 explicit GroppPCG(const MatrixType& matrix, const FilterType& filter,
69 std::shared_ptr<PrecondType> precond = nullptr) :
70 BaseClass("GroppPCG", precond),
71 _system_matrix(matrix),
72 _system_filter(filter)
73 {
74 // set communicator by system matrix
75 this->_set_comm_by_matrix(matrix);
76 }
77
97 explicit GroppPCG(const String& section_name, const PropertyMap* section,
98 const MatrixType& matrix, const FilterType& filter,
99 std::shared_ptr<PrecondType> precond = nullptr) :
100 BaseClass("GroppPCG", section_name, section, precond),
101 _system_matrix(matrix),
102 _system_filter(filter)
103 {
104 // set communicator by system matrix
105 this->_set_comm_by_matrix(matrix);
106 }
107
108 virtual String name() const override
109 {
110 return "GroppPCG";
111 }
112
113 virtual void init_symbolic() override
114 {
116 // create temporary vectors
117 _vec_r = this->_system_matrix.create_vector_r();
118 _vec_z = this->_system_matrix.create_vector_r();
119 _vec_s = this->_system_matrix.create_vector_r();
120 _vec_p = this->_system_matrix.create_vector_r();
121 _vec_S = this->_system_matrix.create_vector_r();
122 _vec_Z = this->_system_matrix.create_vector_r();
123 }
124
125 virtual void done_symbolic() override
126 {
127 this->_vec_r.clear();
128 this->_vec_z.clear();
129 this->_vec_s.clear();
130 this->_vec_p.clear();
131 this->_vec_S.clear();
132 this->_vec_Z.clear();
134 }
135
136 virtual Status apply(VectorType& vec_cor, const VectorType& vec_def) override
137 {
138 // save defect
139 this->_vec_r.copy(vec_def);
140
141 // clear solution vector
142 vec_cor.format();
143
144 // apply solver
145 this->_status = _apply_intern(vec_cor, vec_def);
146
147 // plot summary
148 this->plot_summary();
149
150 // return status
151 return this->_status;
152 }
153
154 virtual Status correct(VectorType& vec_sol, const VectorType& vec_rhs) override
155 {
156 // compute defect
157 this->_system_matrix.apply(this->_vec_r, vec_sol, vec_rhs, -DataType(1));
158 this->_system_filter.filter_def(this->_vec_r);
159
160 // apply solver
161 this->_status = _apply_intern(vec_sol, vec_rhs);
162
163 // plot summary
164 this->plot_summary();
165
166 // return status
167 return this->_status;
168 }
169
170 protected:
171 virtual Status _apply_intern(VectorType& vec_sol, const VectorType& DOXY(vec_rhs))
172 {
173 IterationStats pre_iter(*this);
174 Statistics::add_solver_expression(std::make_shared<ExpressionStartSolve>(this->name()));
175
176 const MatrixType& matrix(this->_system_matrix);
177 const FilterType& filter(this->_system_filter);
178 VectorType& vec_r(this->_vec_r);
179 VectorType& vec_z(this->_vec_z);
180 VectorType& vec_s(this->_vec_s);
181 VectorType& vec_p(this->_vec_p);
182 VectorType& vec_S(this->_vec_S);
183 VectorType& vec_Z(this->_vec_Z);
184
185 DataType gamma, gamma_new, beta, alpha, t;
186 gamma = DataType(0);
187 gamma_new = DataType(0);
188 beta = DataType(0);
189 alpha = DataType(0);
190 t = DataType(0);
191
192 Status status = this->_set_initial_defect(vec_r, vec_sol);
193 if(status != Status::progress)
194 {
195 pre_iter.destroy();
196 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), status, this->get_num_iter()));
197 return status;
198 }
199
200 if(!this->_apply_precond(vec_z, vec_r, filter))
201 {
202 pre_iter.destroy();
203 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), Status::aborted, this->get_num_iter()));
204 return Status::aborted;
205 }
206
207 vec_p.copy(vec_z);
208
209 gamma = vec_z.dot(vec_r);
210
211 matrix.apply(vec_s, vec_p);
212 filter.filter_def(vec_s);
213
214 pre_iter.destroy();
215
216 // start iterating
217 while(status == Status::progress)
218 {
219 IterationStats stat(*this);
220
221 auto dot_t = vec_s.dot_async(vec_p);
222 if(!this->_apply_precond(vec_S, vec_s, filter))
223 {
224 stat.destroy();
225 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), Status::aborted, this->get_num_iter()));
226 return Status::aborted;
227 }
228 t = dot_t.wait();
229
230 alpha = gamma / t;
231
232 vec_r.axpy(vec_s, -alpha);
233 auto norm_def_cur = vec_r.norm2_async();
234
235 vec_sol.axpy(vec_p, alpha);
236
237 vec_z.axpy(vec_S, -alpha);
238
239 auto dot_gamma_new = vec_r.dot_async(vec_z);
240 matrix.apply(vec_Z, vec_z);
241 filter.filter_def(vec_Z);
242
243 gamma_new = dot_gamma_new.wait();
244 beta = gamma_new / gamma;
245 gamma = gamma_new;
246
247 vec_p.scale(vec_p, beta);
248 vec_p.axpy(vec_z);
249 vec_s.scale(vec_s, beta);
250 vec_s.axpy(vec_Z);
251
252 status = this->_update_defect(norm_def_cur.wait());
253 if(status != Status::progress)
254 {
255 stat.destroy();
256 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), status, this->get_num_iter()));
257 return status;
258 }
259 }
260
261 // we should never reach this point...
262 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), Status::undefined, this->get_num_iter()));
263 return Status::undefined;
264 }
265 }; // class GroppPCG<...>
266
282 template<typename Matrix_, typename Filter_>
283 inline std::shared_ptr<GroppPCG<Matrix_, Filter_>> new_gropppcg(
284 const Matrix_& matrix, const Filter_& filter,
285 std::shared_ptr<SolverBase<typename Matrix_::VectorTypeL>> precond = nullptr)
286 {
287 return std::make_shared<GroppPCG<Matrix_, Filter_>>(matrix, filter, precond);
288 }
289
311 template<typename Matrix_, typename Filter_>
312 inline std::shared_ptr<GroppPCG<Matrix_, Filter_>> new_gropppcg(
313 const String& section_name, const PropertyMap* section,
314 const Matrix_& matrix, const Filter_& filter,
315 std::shared_ptr<SolverBase<typename Matrix_::VectorTypeL>> precond = nullptr)
316 {
317 return std::make_shared<GroppPCG<Matrix_, Filter_>>(section_name, section, matrix, filter, precond);
318 }
319 } // namespace Solver
320} // namespace FEAT
A class organizing a tree of key-value pairs.
(Preconditioned) pipelined Conjugate-Gradient solver implementation from Bill Gropp
Definition: gropppcg.hpp:37
const FilterType & _system_filter
the filter for the solver
Definition: gropppcg.hpp:51
virtual void done_symbolic() override
Symbolic finalization method.
Definition: gropppcg.hpp:125
GroppPCG(const MatrixType &matrix, const FilterType &filter, std::shared_ptr< PrecondType > precond=nullptr)
Constructor.
Definition: gropppcg.hpp:68
GroppPCG(const String &section_name, const PropertyMap *section, const MatrixType &matrix, const FilterType &filter, std::shared_ptr< PrecondType > precond=nullptr)
Constructor using a PropertyMap.
Definition: gropppcg.hpp:97
VectorType _vec_r
temporary vectors
Definition: gropppcg.hpp:53
virtual void init_symbolic() override
Symbolic initialization method.
Definition: gropppcg.hpp:113
virtual Status _apply_intern(VectorType &vec_sol, const VectorType &vec_rhs)
Definition: gropppcg.hpp:171
virtual String name() const override
Returns a descriptive string.
Definition: gropppcg.hpp:108
const MatrixType & _system_matrix
the matrix for the solver
Definition: gropppcg.hpp:49
Helper class for iteration statistics collection.
Definition: base.hpp:392
void destroy()
destroy the objects contents (and generate Statistics::expression) before the actual destructor call
Definition: base.hpp:464
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 _update_defect(const DataType def_cur_norm)
Internal function: sets the new (next) defect norm.
Definition: iterative.hpp:970
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
Abstract base-class for preconditioned iterative solvers.
Definition: iterative.hpp:1027
virtual void init_symbolic() override
Symbolic initialization method.
Definition: iterative.hpp:1086
bool _apply_precond(VectorType &vec_cor, const VectorType &vec_def, const Filter_ &filter)
Applies the preconditioner onto a defect vector.
Definition: iterative.hpp:1140
virtual void done_symbolic() override
Symbolic finalization method.
Definition: iterative.hpp:1110
Polymorphic solver interface.
Definition: base.hpp:183
String class implementation.
Definition: string.hpp:47
Status
Solver status return codes enumeration.
Definition: base.hpp:47
@ progress
continue iteration (internal use only)
@ undefined
undefined status
@ aborted
premature abort (solver aborted due to internal errors or preconditioner failure)
std::shared_ptr< GroppPCG< Matrix_, Filter_ > > new_gropppcg(const Matrix_ &matrix, const Filter_ &filter, std::shared_ptr< SolverBase< typename Matrix_::VectorTypeL > > precond=nullptr)
Creates a new GroppPCG solver object.
Definition: gropppcg.hpp:283
FEAT namespace.
Definition: adjactor.hpp:12