Arcane  4.2.3.0
Developer documentation
Loading...
Searching...
No Matches
PoissonProblemGenerator.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/* PoissonProblemGenerator.h (C) 2000-2026 */
9/* */
10/* Helper class to generate a matrix for Poisson problem. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_ALINA_POISSONPROBLEMGENERATOR_H
13#define ARCCORE_ALINA_POISSONPROBLEMGENERATOR_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16/*---------------------------------------------------------------------------*/
17/*
18 * This file is based on the work on AMGCL library (version march 2026)
19 * which can be found at https://github.com/ddemidov/amgcl.
20 *
21 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
22 * SPDX-License-Identifier: MIT
23 */
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27#include "arccore/alina/ValueTypeInterface.h"
28
29#include <vector>
30#include <iostream>
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35namespace Arcane::Alina
36{
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
42{
43 public:
44
45 // Generates matrix for poisson problem in a unit cube.
46 template <typename ValueType, typename ColType, typename PtrType, typename RhsType>
47 static PtrType
48 createSequentialMatrix(Int32 n,
49 std::vector<ValueType>& val,
50 std::vector<ColType>& col,
51 std::vector<PtrType>& ptr,
52 std::vector<RhsType>& rhs,
53 double anisotropy = 1.0)
54 {
55 // In sequential, the global size never exceed 2^31.
56 PtrType n3 = n * n * n;
57
58 ptr.clear();
59 col.clear();
60 val.clear();
61 rhs.clear();
62
63 ptr.reserve(n3 + 1);
64 col.reserve(n3 * 7);
65 val.reserve(n3 * 7);
66 rhs.reserve(n3);
67
68 const auto one = Arcane::Alina::math::identity<ValueType>();
69
70 double hx = 1;
71 double hy = hx * anisotropy;
72 double hz = hy * anisotropy;
73
74 ptr.push_back(0);
75 for (ColType k = 0, idx = 0; k < n; ++k) {
76 for (int j = 0; j < n; ++j) {
77 for (int i = 0; i < n; ++i, ++idx) {
78 if (k > 0) {
79 col.push_back(idx - n * n);
80 val.push_back(-1.0 / (hz * hz) * one);
81 }
82
83 if (j > 0) {
84 col.push_back(idx - n);
85 val.push_back(-1.0 / (hy * hy) * one);
86 }
87
88 if (i > 0) {
89 col.push_back(idx - 1);
90 val.push_back(-1.0 / (hx * hx) * one);
91 }
92
93 col.push_back(idx);
94 val.push_back((2 / (hx * hx) + 2 / (hy * hy) + 2 / (hz * hz)) * one);
95
96 if (i + 1 < n) {
97 col.push_back(idx + 1);
98 val.push_back(-1.0 / (hx * hx) * one);
99 }
100
101 if (j + 1 < n) {
102 col.push_back(idx + n);
103 val.push_back(-1.0 / (hy * hy) * one);
104 }
105
106 if (k + 1 < n) {
107 col.push_back(idx + n * n);
108 val.push_back(-1.0 / (hz * hz) * one);
109 }
110
111 rhs.push_back(Arcane::Alina::math::constant<RhsType>(1.0));
112 ptr.push_back(static_cast<PtrType>(col.size()));
113 }
114 }
115 }
116
117 return n3;
118 }
119
120 //---------------------------------------------------------------------------
121 // Generates a distributed matrix for poisson problem in a unit cube
122 template <typename ValueType, typename ColType, typename PtrType, typename RhsType>
123 static PtrType
124 createDistributedMatrix(int comm_rank, int comm_size,
125 Arcane::Int32 n, int block_size,
126 std::vector<PtrType>& ptr,
127 std::vector<ColType>& col,
128 std::vector<ValueType>& val,
129 std::vector<RhsType>& rhs)
130 {
131 // We use `PtrType` for multiplication because the global size may exceed
132 // the maximum value of Int32
133 PtrType nx = n;
134 PtrType n3 = nx * nx * nx;
135
136 PtrType chunk = (n3 + comm_size - 1) / comm_size;
137 if (chunk % block_size != 0) {
138 chunk += block_size - chunk % block_size;
139 }
140 PtrType row_beg = std::min(n3, chunk * comm_rank);
141 PtrType row_end = std::min(n3, row_beg + chunk);
142 chunk = row_end - row_beg;
143
144 ptr.clear();
145 ptr.reserve(chunk + 1);
146 col.clear();
147 col.reserve(chunk * 7);
148 val.clear();
149 val.reserve(chunk * 7);
150
151 rhs.resize(chunk);
152 std::fill(rhs.begin(), rhs.end(), 1.0);
153
154 const double h2i = (n - 1) * (n - 1);
155 ptr.push_back(0);
156
157 for (PtrType idx = row_beg; idx < row_end; ++idx) {
158 PtrType k = idx / (n * n);
159 PtrType j = (idx / n) % n;
160 PtrType i = idx % n;
161
162 if (k > 0) {
163 col.push_back(idx - n * n);
164 val.push_back(-h2i);
165 }
166
167 if (j > 0) {
168 col.push_back(idx - n);
169 val.push_back(-h2i);
170 }
171
172 if (i > 0) {
173 col.push_back(idx - 1);
174 val.push_back(-h2i);
175 }
176
177 col.push_back(idx);
178 val.push_back(6 * h2i);
179
180 if (i + 1 < n) {
181 col.push_back(idx + 1);
182 val.push_back(-h2i);
183 }
184
185 if (j + 1 < n) {
186 col.push_back(idx + n);
187 val.push_back(-h2i);
188 }
189
190 if (k + 1 < n) {
191 col.push_back(idx + n * n);
192 val.push_back(-h2i);
193 }
194
195 ptr.push_back(col.size());
196 }
197
198 return chunk;
199 }
200};
201
202/*---------------------------------------------------------------------------*/
203/*---------------------------------------------------------------------------*/
204
205} // namespace Arcane::Alina
206
207/*---------------------------------------------------------------------------*/
208/*---------------------------------------------------------------------------*/
209
210#endif
std::int32_t Int32
Signed integer type of 32 bits.