Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
EigenBackend.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/*---------------------------------------------------------------------------*/
8/* EigenBackend.h (C) 2000-2026 */
9/* */
10/* Backend to use types defines in the Eigen library. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_ALINA_EIGENBACKEND_H
13#define ARCCORE_ALINA_EIGENBACKEND_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16/*
17 * This file is based on the work on AMGCL library (version march 2026)
18 * which can be found at https://github.com/ddemidov/amgcl.
19 *
20 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
21 * SPDX-License-Identifier: MIT
22 */
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26#include "arccore/alina/EigenAdapter.h"
27#include "arccore/alina/SkylineLUSolver.h"
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32namespace Arcane::Alina::backend
33{
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
46template <typename real>
48{
49 typedef real value_type;
50 typedef ptrdiff_t index_type;
51 typedef ptrdiff_t col_type;
52 typedef ptrdiff_t ptr_type;
53
54 typedef Eigen::Map<Eigen::SparseMatrix<value_type, Eigen::RowMajor, index_type>> matrix;
55
56 typedef Eigen::Matrix<value_type, Eigen::Dynamic, 1> vector;
57 typedef Eigen::Matrix<value_type, Eigen::Dynamic, 1> matrix_diagonal;
58
59 typedef solver::SkylineLUSolver<real> direct_solver;
60
61 struct provides_row_iterator : std::true_type
62 {};
63
66
67 static std::string name() { return "eigen"; }
68
70 static std::shared_ptr<matrix>
71 copy_matrix(std::shared_ptr<typename BuiltinBackend<real>::matrix> A, const params&)
72 {
73 const typename BuiltinBackend<real>::matrix& a = *A;
74
75 return std::shared_ptr<matrix>(new matrix(
76 nbRow(*A), nbColumn(*A), nonzeros(*A),
77 const_cast<index_type*>(a.ptr.data()),
78 const_cast<index_type*>(a.col.data()),
79 const_cast<value_type*>(a.val.data())),
80 hold_host(A));
81 }
82
84 static std::shared_ptr<vector>
85 copy_vector(typename BuiltinBackend<real>::vector const& x, const params&)
86 {
87 return std::make_shared<vector>(
88 Eigen::Map<const vector>(x.data(), x.size()));
89 }
90
92 static std::shared_ptr<vector>
93 copy_vector(std::shared_ptr<typename BuiltinBackend<real>::vector> x, const params& prm)
94 {
95 return copy_vector(*x, prm);
96 }
97
99 static std::shared_ptr<vector>
100 create_vector(size_t size, const params&)
101 {
102 return std::make_shared<vector>(size);
103 }
104
106 static std::shared_ptr<direct_solver>
107 create_solver(std::shared_ptr<typename BuiltinBackend<real>::matrix> A, const params&)
108 {
109 return std::make_shared<direct_solver>(*A);
110 }
111
112 private:
113
114 struct hold_host
115 {
116 typedef std::shared_ptr<CSRMatrix<real, ptrdiff_t, ptrdiff_t>> host_matrix;
117 host_matrix host;
118
119 hold_host(host_matrix host)
120 : host(host)
121 {}
122
123 void operator()(matrix* ptr) const
124 {
125 delete ptr;
126 }
127 };
128};
129
130template <class Alpha, class M, class V1, class Beta, class V2>
131struct spmv_impl<Alpha, M, V1, Beta, V2,
132 typename std::enable_if<
133 is_eigen_sparse_matrix<M>::value &&
134 is_eigen_type<V1>::value &&
135 is_eigen_type<V2>::value>::type>
136{
137 static void apply(Alpha alpha, const M& A, const V1& x, Beta beta, V2& y)
138 {
139 if (!math::is_zero(beta))
140 y = alpha * A * x + beta * y;
141 else
142 y = alpha * A * x;
143 }
144};
145
146template <class M, class V1, class V2, class V3>
147struct residual_impl<M, V1, V2, V3,
148 typename std::enable_if<
149 is_eigen_sparse_matrix<M>::value &&
150 is_eigen_type<V1>::value &&
151 is_eigen_type<V2>::value &&
152 is_eigen_type<V3>::value>::type>
153{
154 static void apply(const V1& rhs, const M& A, const V2& x, V3& r)
155 {
156 r = rhs - A * x;
157 }
158};
159
160template <typename V>
161struct clear_impl<V, typename std::enable_if<is_eigen_type<V>::value>::type>
162{
163 static void apply(V& x)
164 {
165 x.setZero();
166 }
167};
168
169template <class V1, class V2>
170struct inner_product_impl<V1, V2,
171 typename std::enable_if<
172 is_eigen_type<V1>::value &&
173 is_eigen_type<V2>::value>::type>
174{
175 typedef typename value_type<V1>::type real;
176 static real get(const V1& x, const V2& y)
177 {
178 return y.dot(x);
179 }
180};
181
182template <class A, class V1, class B, class V2>
183struct axpby_impl<A, V1, B, V2,
184 typename std::enable_if<
185 is_eigen_type<V1>::value &&
186 is_eigen_type<V2>::value>::type>
187{
188 static void apply(A a, const V1& x, B b, V2& y)
189 {
190 if (!math::is_zero(b))
191 y = a * x + b * y;
192 else
193 y = a * x;
194 }
195};
196
197template <class A, class V1, class B, class V2, class C, class V3>
198struct axpbypcz_impl<A, V1, B, V2, C, V3,
199 typename std::enable_if<
200 is_eigen_type<V1>::value &&
201 is_eigen_type<V2>::value &&
202 is_eigen_type<V3>::value>::type>
203{
204 typedef typename value_type<V1>::type real;
205
206 static void apply(real a, const V1& x, real b, const V2& y, real c, V3& z)
207 {
208 if (!math::is_zero(c))
209 z = a * x + b * y + c * z;
210 else
211 z = a * x + b * y;
212 }
213};
214
215template <class Alpha, class V1, class V2, class Beta, class V3>
216struct vmul_impl<Alpha, V1, V2, Beta, V3,
217 typename std::enable_if<is_eigen_type<V1>::value &&
218 is_eigen_type<V2>::value &&
219 is_eigen_type<V3>::value>::type>
220{
221 static void apply(Alpha a, const V1& x, const V2& y, Beta b, V3& z)
222 {
223 if (!math::is_zero(b))
224 z.array() = a * x.array() * y.array() + b * z.array();
225 else
226 z.array() = a * x.array() * y.array();
227 }
228};
229
230template <class V1, class V2>
231struct copy_impl<V1, V2,
232 typename std::enable_if<
233 is_eigen_type<V1>::value &&
234 is_eigen_type<V2>::value>::type>
235{
236 static void apply(const V1& x, V2& y)
237 {
238 y = x;
239 }
240};
241
242} // namespace Arcane::Alina::backend
243
244#endif
Class to handle empty parameters list.
Definition AlinaUtils.h:90
Direct solver that uses Skyline LU factorization.
static std::shared_ptr< vector > copy_vector(typename BuiltinBackend< real >::vector const &x, const params &)
Copy vector from builtin backend.
Alina::detail::empty_params params
Backend parameters.
static std::shared_ptr< direct_solver > create_solver(std::shared_ptr< typename BuiltinBackend< real >::matrix > A, const params &)
Create direct solver for coarse level.
static std::shared_ptr< vector > create_vector(size_t size, const params &)
Create vector of the specified size.
static std::shared_ptr< matrix > copy_matrix(std::shared_ptr< typename BuiltinBackend< real >::matrix > A, const params &)
Copy matrix from builtin backend.
static std::shared_ptr< vector > copy_vector(std::shared_ptr< typename BuiltinBackend< real >::vector > x, const params &prm)
Copy vector from builtin backend.
Implementation for linear combination of two vectors.
Implementation for linear combination of three vectors.
Implementation for zeroing out a vector.
Implementation for vector copy.
Implementation for inner product.
Implementation for residual error compuatation.
Implementation for matrix-vector product.
Implementation for element-wize vector product.