Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
NeumannPolyPreconditioner.h
1/*
2 * Copyright 2020 IFPEN-CEA
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * SPDX-License-Identifier: Apache-2.0
17 */
18#pragma once
19
20#include <random>
21#include <iostream>
22
28namespace Alien
29{
30
31template <typename AlgebraT>
32class NeumannPolyPreconditioner
33{
34 public:
35 // clang-format off
36 typedef AlgebraT AlgebraType ;
37 typedef typename AlgebraType::Matrix MatrixType;
38 typedef typename AlgebraType::Vector VectorType;
39 typedef typename MatrixType::ValueType ValueType;
40 // clang-format on
41
42 NeumannPolyPreconditioner(AlgebraType& algebra,
43 MatrixType const& matrix,
44 ValueType factor,
45 int polynome_order,
46 int factor_max_iter,
47 ITraceMng* trace_mng = nullptr)
48 : m_algebra(algebra)
49 , m_matrix(matrix)
50 , m_factor(factor)
51 , m_polynome_order(polynome_order)
52 , m_factor_max_iter(factor_max_iter)
53 , m_trace_mng(trace_mng)
54 {
55 }
56
57 virtual ~NeumannPolyPreconditioner()
58 {
59 m_algebra.free(m_y);
60 m_algebra.free(m_yy);
61 };
62
63 void setOutputLevel(int level)
64 {
65 m_output_level = level;
66 }
67
68 void init()
69 {
70 m_algebra.allocate(AlgebraType::resource(m_matrix), m_y, m_yy);
71 m_algebra.assign(m_y, 0.);
72 m_algebra.assign(m_yy, 0.);
73
74 if (m_factor == 0) {
75 computeFactor();
76 }
77 if (m_trace_mng) {
78 m_trace_mng->info() << "Neunmann Preconditioner Info :";
79 m_trace_mng->info() << "Polynome Degree : " << m_polynome_order;
80 m_trace_mng->info() << "Neunmann Factor : " << m_factor;
81 m_trace_mng->info() << "Power Method Max Iter : " << m_factor_max_iter;
82 }
83 }
84
85 void solve(const VectorType& x,
86 VectorType& y
87 )
88 {
89
90 m_algebra.copy(x, y);
91 for (int i = 0; i < m_polynome_order; ++i) {
92 // yy = G*y
93 evalG(y, m_y);
94 //yy = x + yy = x + Gy
95 m_algebra.axpy(1., x, m_y);
96 //y = yy = x + G*y
97 m_algebra.copy(m_y, y);
98 }
99 // y=factor*Pn(x)
100 m_algebra.scal(m_factor, y);
101 }
102
103 void solve(AlgebraType& algebra,
104 VectorType const& x,
105 VectorType& y) const
106 {
107
108 algebra.copy(x, y);
109 for (int i = 0; i < m_polynome_order; ++i) {
110 // yy = G*y
111 evalG(algebra, y, m_y);
112 //yy = x + yy = x + Gy
113 algebra.axpy(1., x, m_y);
114 //y = yy = x + G*y
115 algebra.copy(m_y, y);
116 }
117 // y=factor*Pn(x)
118 algebra.scal(m_factor, y);
119 }
120
121 void evalG(AlgebraType& algebra,
122 const VectorType& x,
123 VectorType& y) const
124 {
125 // yy = A.x
126 algebra.mult(m_matrix, x, m_yy);
127 algebra.copy(x, y);
128 // y+= -factor * yy
129 algebra.axpy(-m_factor, m_yy, y);
130 }
131
132 void evalG(const VectorType& x,
133 VectorType& y)
134 {
135 // yy = A.x
136 m_algebra.mult(m_matrix, x, m_yy);
137 m_algebra.copy(x, y);
138 // y+= -factor * yy
139 m_algebra.axpy(-m_factor, m_yy, y);
140 }
141
142 void computeFactor()
143 {
144 VectorType x;
145 m_algebra.allocate(AlgebraType::resource(m_matrix), x);
146
147 //m_algebra.assign(x,1.) ;
148 std::random_device rd;
149 std::mt19937 gen(rd());
150 std::uniform_real_distribution<> dis(-1., 1.);
151 /*
152 for (std::size_t i = 0; i < x.getAllocSize(); ++i)
153 {
154 x[i] =dis(gen);
155 }*/
156 m_algebra.assign(x, [&]([[maybe_unused]] auto i) {
157 return dis(gen);
158 });
159
160 m_algebra.mult(m_matrix, x, m_y);
161 ValueType norme2_k = m_algebra.norm2(m_y);
162 for (int i = 0; i < m_factor_max_iter; ++i) {
163 m_algebra.copy(m_y, x);
164 m_algebra.mult(m_matrix, x, m_y);
165 ValueType norme2 = m_algebra.norm2(m_y);
166 m_factor = norme2 / norme2_k;
167 norme2_k = norme2;
168 }
169 m_factor = 1. / (m_factor);
170
171 if (m_trace_mng)
172 m_trace_mng->info() << "Poly Factor : " << m_factor;
173
174 m_algebra.free(x);
175 }
176
177 private:
178 // clang-format off
179 AlgebraType& m_algebra;
180
182 MatrixType const& m_matrix ;
183
185 ValueType m_factor = 0.;
186 int m_polynome_order = 3 ;
187 int m_factor_max_iter = 10 ;
188
189 mutable VectorType m_y;
190 mutable VectorType m_yy;
191
192 ITraceMng* m_trace_mng = nullptr;
193 int m_output_level = 0 ;
194 // clang-format on
195};
196
197} // namespace Alien
MatrixType const & m_matrix
matrix a preconditioner
void evalG(AlgebraType &algebra, const VectorType &x, VectorType &y) const
void evalG(const VectorType &x, VectorType &y)
void solve(const VectorType &x, VectorType &y)
ValueType m_factor
facteur d'acceleration
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17