Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
AMGSolverT.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7#pragma once
8
9#include <ostream>
10#include <vector>
11
14#include <alien/core/backend/KernelSolverT.h>
16
17namespace Alien
18{
19
20template <typename TagT,
21 typename AlgebraT,
22 typename SolverT,
23 typename PrecondT>
24class AMGSolverT
25 : public KernelSolverT<TagT>
26{
27 public:
28 // clang-format off
29 using KernelSolverType = KernelSolverT<TagT> ;
30 using SolverType = SolverT;
31 using PrecondType = PrecondT;
32 using AlgebraType = AlgebraT;
33 using MatrixType = typename AlgebraType::MatrixType ;
34 using VectorType = typename AlgebraType::VectorType ;
35 using ValueType = typename AlgebraType::ValueType ;
36 // clang-format on
37 AMGSolverT(AlgebraT& alg, SolverT& solver, PrecondT& precond)
38 : m_algebra(alg)
39 , m_solver(solver)
40 , m_precond(precond)
41 {}
42
43 virtual ~AMGSolverT()
44 {
45 end() ;
46 }
47
48 void init()
49 {
50 if constexpr (requires{m_solver.init();}) {
51 m_solver.init() ;
52 }
53 }
54
55 void start() {
56 if constexpr (requires{m_solver.start();}) {
57 m_solver.init() ;
58 }
59
60 }
61
63 void init(MatrixType const& A) {
64 m_matrix = &A ;
65 m_precond.init() ;
66 }
67
68 void end() {
69 if constexpr (requires{m_solver.end();}) {
70 m_solver.end() ;
71 }
72 }
73
74 bool solve(const VectorType& b, VectorType& x)
75 {
76 auto iter = Alien::Iteration<AlgebraType>{m_algebra,b,0.,1,nullptr} ;
77 m_solver.solve(m_precond,iter,*m_matrix,b,x) ;
78 return true ;
79 }
80 private:
81 AlgebraType& m_algebra ;
82 SolverType& m_solver;
83 PrecondType& m_precond ;
84
85 MatrixType const* m_matrix = nullptr ;
86};
87
88template <typename TagT,
89 typename AlgebraT,
90 typename AMGSolverTagT>
91class KernelAMGSolverT
92 : public KernelSolverT<TagT>
93{
94 public:
95 // clang-format off
96 using BaseSolverType = KernelSolverT<TagT> ;
97 using AlgebraType = AlgebraT;
98 using MatrixType = typename AlgebraType::MatrixType ;
99 using VectorType = typename AlgebraType::VectorType ;
100 using ValueType = typename AlgebraType::ValueType ;
101 using DefMatrixTagType = Alien::BackEnd::tag::simplecsr ;
102
103 using SolverMatrixType = typename AlgebraTraits<AMGSolverTagT>::matrix_type;
104 using SolverVectorType = typename AlgebraTraits<AMGSolverTagT>::vector_type;
105 using SolverAlgebraType = typename AlgebraTraits<AMGSolverTagT>::algebra_type;
106 using AMGSolverType = KernelSolverT<AMGSolverTagT>;
107
108 using MatrixConvType = MatrixConverterT<TagT,AMGSolverTagT> ;
109 using DefMatrixConvType = MatrixConverterT<DefMatrixTagType,AMGSolverTagT>;
110 using VectorConvFromType = VectorConverterT<TagT,AMGSolverTagT> ;
111 using VectorConvToType = VectorConverterT<AMGSolverTagT,TagT> ;
112
113 // clang-format on
114 KernelAMGSolverT(AlgebraT& alg, AMGSolverType* solver)
115 : BaseSolverType()
116 , m_algebra(alg)
117 , m_amg_solver(solver)
118 {
119 const BackEndId backend_id = AlgebraTraits<TagT>::BackEndId() ;
120 const BackEndId solver_backend_id = AlgebraTraits<AMGSolverTagT>::BackEndId() ;
121 m_matrix_converter =
122 MatrixConverterRegisterer::getConverter(backend_id,solver_backend_id);
123 if(m_matrix_converter==nullptr)
124 {
125 const BackEndId def_backend_id = AlgebraTraits<DefMatrixTagType>::name() ;
126 m_def_matrix_converter =
127 dynamic_cast<DefMatrixConvType*>(MatrixConverterRegisterer::getConverter(def_backend_id,solver_backend_id));
128 }
129 m_vector_converter_from =
130 VectorConverterRegisterer::getConverter(backend_id,solver_backend_id);
131 m_vector_converter_to =
132 VectorConverterRegisterer::getConverter(solver_backend_id,backend_id);
133 }
134
135 // clang-format on
136 KernelAMGSolverT(AlgebraT& alg, Alien::ILinearSolver* solver)
137 : BaseSolverType()
138 , m_algebra(alg)
139 {
140 auto solver_ptr = dynamic_cast<Alien::LinearSolver<AMGSolverTagT>*>(solver) ;
141 if(solver_ptr)
142 m_amg_solver = dynamic_cast<AMGSolverType*>(solver_ptr->implem()) ;
143 else
144 m_amg_solver = dynamic_cast<AMGSolverType*>(solver) ;
145 assert(m_amg_solver) ;
146
147 const BackEndId backend_id = AlgebraTraits<TagT>::name() ;
148 const BackEndId solver_backend_id = AlgebraTraits<AMGSolverTagT>::name() ;
149 m_matrix_converter =
150 dynamic_cast<MatrixConvType*>(MatrixConverterRegisterer::getConverter(backend_id,solver_backend_id));
151 //if(m_matrix_converter==nullptr)
152 {
153 const BackEndId def_backend_id = AlgebraTraits<DefMatrixTagType>::name() ;
154 m_def_matrix_converter =
155 dynamic_cast<DefMatrixConvType*>(MatrixConverterRegisterer::getConverter(def_backend_id,solver_backend_id));
156 }
157
158 m_vector_converter_from =
159 dynamic_cast<VectorConvFromType*>(VectorConverterRegisterer::getConverter(backend_id,solver_backend_id));
160 m_vector_converter_to =
161 dynamic_cast<VectorConvToType*>(VectorConverterRegisterer::getConverter(solver_backend_id,backend_id));
162 }
163
164 virtual ~KernelAMGSolverT()
165 {
166 end() ;
167 }
168
169 void init()
170 {
171 m_amg_solver->init() ;
172 }
173
174 void start() {
175
176 }
177
179 void init(MatrixType const& A)
180 {
181 m_matrix = &A ;
182 if(m_solver_matrix.get()==nullptr)
183 {
184 auto ptr = new SolverMatrixType(m_matrix->impls()) ;
185 m_solver_matrix.reset(ptr) ;
186 }
187 if(m_matrix_converter)
188 m_matrix_converter->convert(A, *m_solver_matrix);
189 else
190 {
191 auto const& defA = m_matrix->impls()->template get<DefMatrixTagType>() ;
192 m_def_matrix_converter->convert(defA, *m_solver_matrix);
193 }
194 m_amg_solver->init(*m_solver_matrix) ;
195 }
196
197 void end() {
198 m_solver_b.reset() ;
199 m_solver_x.reset();
200 m_solver_matrix.reset() ;
201 if constexpr (requires{m_amg_solver->end();}) {
202 m_amg_solver->end() ;
203 }
204 }
205
206 bool solve(const VectorType& b, VectorType& x)
207 {
208 if(m_solver_b.get()==nullptr)
209 {
210 auto ptr = new SolverVectorType(nullptr) ;
211 ptr->init(AlgebraType::resource(*m_matrix) ,true) ;
212 m_solver_b.reset(ptr) ;
213 }
214 m_vector_converter_from->convert(b, *m_solver_b);
215 if(m_solver_x.get()==nullptr)
216 {
217 auto ptr = new SolverVectorType(nullptr) ;
218 ptr->init(AlgebraType::resource(*m_matrix),true) ;
219 m_solver_x.reset(ptr) ;
220 }
221 m_solver_x->setValuesToZeros() ;
222
223 m_amg_solver->solve(*m_solver_b,*m_solver_x) ;
224 m_vector_converter_to->convert(*m_solver_x,x);
225 return true ;
226 }
227 private:
228 AlgebraType& m_algebra ;
229 AMGSolverType* m_amg_solver = nullptr;
230 MatrixType const* m_matrix = nullptr ;
231 std::unique_ptr<SolverMatrixType> m_solver_matrix;
232 std::unique_ptr<SolverVectorType> m_solver_b;
233 std::unique_ptr<SolverVectorType> m_solver_x;
234 MatrixConvType* m_matrix_converter = nullptr ;
235 DefMatrixConvType* m_def_matrix_converter = nullptr ;
236 VectorConvFromType* m_vector_converter_from = nullptr ;
237 VectorConvToType* m_vector_converter_to = nullptr ;
238};
239
240} // namespace Alien
LinearSolver.h.
MatrixConverterRegisterer.h.
VectorConverterRegisterer.h.
void init(MatrixType const &A)
Initialize the linear solver.
Definition AMGSolverT.h:63
Linear solver interface.
void init(MatrixType const &A)
Initialize the linear solver.
Definition AMGSolverT.h:179
Linear solver interface.
static IMatrixConverter * getConverter(BackEndId from, BackEndId to)
Get the converter from one matrix format to another one.
static IVectorConverter * getConverter(BackEndId from, BackEndId to)
Get the converter from one vector format to another one.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17